| // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s |
| |
| namespace GH62361 { |
| template <typename T, typename U = void*> struct B { // expected-note 14{{candidate}} |
| B() // expected-note 7{{not viable}} |
| requires __is_same(T, int); // expected-note 7{{because '__is_same(char, int)' evaluated to false}} |
| }; |
| |
| template <typename U> struct B<void, U> : B<int, U> { |
| using B<int, U>::B; |
| }; |
| |
| template<typename T> |
| void g(B<T>); // expected-note {{cannot convert}} |
| |
| void f1() { |
| B<void> b1; |
| B<void> b2{}; |
| B<void> b3 = {}; |
| new B<void>{}; |
| new B<void>(); |
| g<void>({}); |
| B<void>{}; |
| B<void>(); |
| } |
| |
| void f2() { |
| B<int> b1; |
| B<int> b2{}; |
| B<int> b3 = {}; |
| new B<int>{}; |
| new B<int>(); |
| g<int>({}); |
| B<int>{}; |
| B<int>(); |
| } |
| |
| void f3() { |
| B<char> b1; // expected-error {{no matching constructor}} |
| B<char> b2{}; // expected-error {{no matching constructor}} |
| B<char> b3 = {}; // expected-error {{no matching constructor}} |
| new B<char>{}; // expected-error {{no matching constructor}} |
| new B<char>(); // expected-error {{no matching constructor}} |
| g<char>({}); // expected-error {{no matching function}} |
| B<char>{}; // expected-error {{no matching constructor}} |
| B<char>(); // expected-error {{no matching constructor}} |
| } |
| } |
| |
| namespace no_early_substitution { |
| template <typename T> concept X = true; |
| |
| struct A {}; |
| |
| template <typename T> struct B { |
| B() requires X<T*>; |
| B(); |
| }; |
| |
| template <typename U = int, typename V = A> |
| struct C : public B<V&> { |
| using B<V&>::B; |
| }; |
| |
| void foo() { |
| // OK, we only substitute T ~> V& into X<T*> in a SFINAE context, |
| // during satisfaction checks. |
| C(); |
| } |
| } |
| |
| namespace GH62362 { |
| template<typename T> |
| concept C = true; |
| template <typename T> struct Test { |
| Test() |
| requires(C<T>); |
| }; |
| struct Bar : public Test<int> { |
| using Test<int>::Test; |
| }; |
| template <> |
| struct Test<void> : public Test<int> { |
| using Test<int>::Test; |
| }; |
| |
| void foo() { |
| Bar(); |
| Test<void>(); |
| } |
| } |