diff options
Diffstat (limited to 'clang/test/SemaTemplate')
-rw-r--r-- | clang/test/SemaTemplate/GH161657.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaTemplate/concepts-recovery-expr.cpp | 32 | ||||
-rw-r--r-- | clang/test/SemaTemplate/concepts-recursive-inst.cpp | 27 | ||||
-rw-r--r-- | clang/test/SemaTemplate/concepts.cpp | 71 | ||||
-rw-r--r-- | clang/test/SemaTemplate/deduction-guide.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-abbreviated-template.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-requires-expr.cpp | 20 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-template-argument.cpp | 97 | ||||
-rw-r--r-- | clang/test/SemaTemplate/pr52970.cpp | 2 |
10 files changed, 217 insertions, 54 deletions
diff --git a/clang/test/SemaTemplate/GH161657.cpp b/clang/test/SemaTemplate/GH161657.cpp index 6ec7931..5ad4dde 100644 --- a/clang/test/SemaTemplate/GH161657.cpp +++ b/clang/test/SemaTemplate/GH161657.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -ffp-exception-behavior=strict -verify %s +// RUN: %clang_cc1 -triple=x86_64 -fsyntax-only -std=c++20 -ffp-exception-behavior=strict -verify %s // expected-no-diagnostics template <class T> struct S { diff --git a/clang/test/SemaTemplate/concepts-recovery-expr.cpp b/clang/test/SemaTemplate/concepts-recovery-expr.cpp index 6bed179..aa4ed53 100644 --- a/clang/test/SemaTemplate/concepts-recovery-expr.cpp +++ b/clang/test/SemaTemplate/concepts-recovery-expr.cpp @@ -4,7 +4,7 @@ constexpr bool CausesRecoveryExpr = "test" + 1.0f; template<typename T> -concept ReferencesCRE = CausesRecoveryExpr; +concept ReferencesCRE = CausesRecoveryExpr; // #subst1 template<typename T> requires CausesRecoveryExpr // #NVC1REQ void NoViableCands1(){} // #NVC1 @@ -19,16 +19,18 @@ void NVCUse() { NoViableCands1<int>(); // expected-error@-1 {{no matching function for call to 'NoViableCands1'}} // expected-note@#NVC1{{candidate template ignored: constraints not satisfied}} + // expected-note@#NVC2REQ{{because 'int' does not satisfy 'ReferencesCRE'}} // expected-note@#NVC1REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} NoViableCands2<int>(); // expected-error@-1 {{no matching function for call to 'NoViableCands2'}} // expected-note@#NVC2{{candidate template ignored: constraints not satisfied}} - // expected-note@#NVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} NoViableCands3<int>(); // expected-error@-1 {{no matching function for call to 'NoViableCands3'}} // expected-note@#NVC3{{candidate template ignored: constraints not satisfied}} - // expected-note@#NVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#NVC3REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } template<typename T> requires CausesRecoveryExpr // #OVC1REQ @@ -58,12 +60,14 @@ void OVCUse() { // expected-error@-1 {{no matching function for call to 'OtherViableCands2'}} // expected-note@#OVC2_ALT {{candidate function}} // expected-note@#OVC2 {{candidate template ignored: constraints not satisfied}} - // expected-note@#OVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#OVC2REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} OtherViableCands3<int>(); // expected-error@-1 {{no matching function for call to 'OtherViableCands3'}} // expected-note@#OVC3_ALT {{candidate function}} // expected-note@#OVC3 {{candidate template ignored: constraints not satisfied}} - // expected-note@#OVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#OVC3REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } template<typename T> requires CausesRecoveryExpr // #OBNVC1REQ @@ -95,13 +99,15 @@ void OBNVCUse() { // expected-note@#OBNVC2_ALT {{candidate template ignored: constraints not satisfied}} // expected-note@#OBNVC2REQ_ALT {{because 'false' evaluated to false}} // expected-note@#OBNVC2 {{candidate template ignored: constraints not satisfied}} - // expected-note@#OBNVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#OBNVC2REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} OtherBadNoViableCands3<int>(); // expected-error@-1 {{no matching function for call to 'OtherBadNoViableCands3'}} // expected-note@#OBNVC3_ALT {{candidate template ignored: constraints not satisfied}} // expected-note@#OBNVC3REQ_ALT {{because 'false' evaluated to false}} // expected-note@#OBNVC3 {{candidate template ignored: constraints not satisfied}} - // expected-note@#OBNVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#OBNVC3REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } @@ -136,12 +142,14 @@ void MemOVCUse() { // expected-error@-1 {{no matching member function for call to 'OtherViableCands2'}} // expected-note@#MEMOVC2_ALT {{candidate function}} // expected-note@#MEMOVC2 {{candidate template ignored: constraints not satisfied}} - // expected-note@#MEMOVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#MEMOVC2REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} S.OtherViableCands3<int>(); // expected-error@-1 {{no matching member function for call to 'OtherViableCands3'}} // expected-note@#MEMOVC3_ALT {{candidate function}} // expected-note@#MEMOVC3 {{candidate template ignored: constraints not satisfied}} - // expected-note@#MEMOVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#MEMOVC3REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } struct StaticOVC { @@ -173,12 +181,14 @@ void StaticMemOVCUse() { // expected-error@-1 {{no matching function for call to 'OtherViableCands2'}} // expected-note@#SMEMOVC2_ALT {{candidate function}} // expected-note@#SMEMOVC2 {{candidate template ignored: constraints not satisfied}} - // expected-note@#SMEMOVC2REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#SMEMOVC2REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} StaticOVC::OtherViableCands3<int>(); // expected-error@-1 {{no matching function for call to 'OtherViableCands3'}} // expected-note@#SMEMOVC3_ALT {{candidate function}} // expected-note@#SMEMOVC3 {{candidate template ignored: constraints not satisfied}} - // expected-note@#SMEMOVC3REQ{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#SMEMOVC3REQ{{because 'int' does not satisfy 'ReferencesCRE'}} + // expected-note@#subst1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} } namespace GH58548 { diff --git a/clang/test/SemaTemplate/concepts-recursive-inst.cpp b/clang/test/SemaTemplate/concepts-recursive-inst.cpp index 097cad1..73dce93 100644 --- a/clang/test/SemaTemplate/concepts-recursive-inst.cpp +++ b/clang/test/SemaTemplate/concepts-recursive-inst.cpp @@ -12,7 +12,7 @@ void g() { // expected-note@#FDEF{{because 'int' does not satisfy 'c'}} // expected-note@#CDEF{{because 'f(t)' would be invalid: no matching function for call to 'f'}} } -} // namespace GH53213 +} // namespace GH53213 namespace GH45736 { struct constrained; @@ -67,15 +67,14 @@ struct my_range{ void baz() { auto it = begin(rng); // #BEGIN_CALL -// expected-error@#INF_BEGIN {{satisfaction of constraint 'Inf<Inf auto>' depends on itself}} -// expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} +// expected-error-re@#INF_REQ {{satisfaction of constraint {{.*}} depends on itself}} +// expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<DirectRecursiveCheck::my_range>' requested here}} // expected-note@#INF_BEGIN_EXPR {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}} // expected-note@#INF_BEGIN_EXPR {{while substituting deduced template arguments into function template 'begin'}} // expected-note@#INF_BEGIN_EXPR {{in instantiation of requirement here}} // expected-note@#INF_REQ {{while substituting template arguments into constraint expression here}} -// expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<DirectRecursiveCheck::my_range>' requested here}} -// expected-note@#INF_BEGIN {{while substituting template arguments into constraint expression here}} -// expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin<DirectRecursiveCheck::my_range>' required here}} +// expected-note@#INF_BEGIN {{while checking the satisfaction of concept 'Inf<struct my_range>' requested here}} +// expected-note@#BEGIN_CALL {{while checking constraint satisfaction for template 'begin<struct my_range>' required here}} // expected-note@#BEGIN_CALL {{while substituting deduced template arguments into function template}} // Fallout of the failure is failed lookup, which is necessary to stop odd @@ -83,6 +82,7 @@ auto it = begin(rng); // #BEGIN_CALL // expected-error@#BEGIN_CALL {{no matching function for call to 'begin'}} // expected-note@#NOTINF_BEGIN {{candidate function}} // expected-note@#INF_BEGIN{{candidate template ignored: constraints not satisfied}} +// expected-note@#INF_BEGIN{{because 'Inf auto' does not satisfy 'Inf}} } } // namespace DirectRecursiveCheck @@ -100,16 +100,17 @@ namespace GH50891 { static_assert(Numeric<Deferred>); // #STATIC_ASSERT // expected-error@#NUMERIC{{satisfaction of constraint 'requires (T a) { foo(a); }' depends on itself}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} - // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}} - // expected-note@#OP_TO {{while substituting template arguments into constraint expression here}} - // expected-note@#FOO_CALL {{while checking constraint satisfaction for template}} - // expected-note@#FOO_CALL {{while substituting deduced template arguments into function template}} - // expected-note@#FOO_CALL {{in instantiation of requirement here}} + // expected-note@#OP_TO {{while checking the satisfaction of concept 'Numeric<Deferred>' requested here}} + // expected-note@#OP_TO {{skipping 1 context}} + // expected-note@#FOO_CALL 2{{while checking constraint satisfaction for template}} + // expected-note@#FOO_CALL 2{{while substituting deduced template arguments into function template}} + // expected-note@#FOO_CALL 2{{in instantiation of requirement here}} // expected-note@#NUMERIC {{while substituting template arguments into constraint expression here}} // expected-error@#STATIC_ASSERT {{static assertion failed}} - // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric<GH50891::Deferred>' requested here}} - // expected-note@#STATIC_ASSERT{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} + // expected-note@#STATIC_ASSERT{{while checking the satisfaction of concept 'Numeric<Deferred>' requested here}} + // expected-note@#STATIC_ASSERT{{because 'Deferred' does not satisfy 'Numeric'}} + // expected-note@#FOO_CALL{{because 'foo(a)' would be invalid}} } // namespace GH50891 diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 209e7dc..6d29f8b 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -1002,7 +1002,7 @@ template<class> concept Irrelevant = false; template <typename T> -concept ErrorRequires = requires(ErrorRequires auto x) { x; }; +concept ErrorRequires = requires(ErrorRequires auto x) { x; }; //#GH54678-ill-formed-concept // expected-error@-1 {{a concept definition cannot refer to itself}} \ // expected-error@-1 {{'auto' not allowed in requires expression parameter}} \ // expected-note@-1 {{declared here}} @@ -1023,8 +1023,7 @@ template<class T> void eee(T t) // expected-note {{candidate template ignored: c requires (Irrelevant<T> || Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'long' does not satisfy 'False'}} template<class T> void fff(T t) // expected-note {{candidate template ignored: constraints not satisfied}} -requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} // expected-note {{'unsigned long' does not satisfy 'False'}} - +requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} // expected-note {{because 'unsigned long' does not satisfy 'False'}} void test() { aaa(42); // expected-error {{no matching function}} bbb(42L); // expected-error{{no matching function}} @@ -1264,12 +1263,7 @@ C auto x = 0; // expected-error@#T_Type {{type 'int' cannot be used prior to '::'}} \ // expected-note@-1 {{in instantiation of default argument}} -// This will be fixed when we merge https://github.com/llvm/llvm-project/pull/141776 -// Which makes us behave like GCC. static_assert(f(0)); -// expected-error@-1 {{no matching function for call}} \ -// expected-note@#GH61824_f {{constraints not satisfied}} \ -// expected-note@#T_Type {{type 'int' cannot be used prior to '::'}} } @@ -1278,4 +1272,65 @@ template <typename T> concept PerfectSquare = [](){} // expected-note 2{{here}} ([](auto) { return true; }) < PerfectSquare <class T>; // expected-error@-1 {{declaration of 'T' shadows template parameter}} \ // expected-error@-1 {{a concept definition cannot refer to itself}} + +} +namespace GH61811{ +template <class T> struct A { static const int x = 42; }; +template <class Ta> concept A42 = A<Ta>::x == 42; +template <class Tv> concept Void = __is_same_as(Tv, void); +template <class Tb, class Ub> concept A42b = Void<Tb> || A42<Ub>; +template <class Tc> concept R42c = A42b<Tc, Tc&>; +static_assert (R42c<void>); +} + +namespace parameter_mapping_regressions { + +namespace case1 { + +template <template <class> class> using __meval = struct __q; +template <template <class> class _Tp> +concept __mvalid = requires { typename __meval<_Tp>; }; +template <class _Fn> +concept __minvocable = __mvalid<_Fn::template __f>; +template <class...> struct __mdefer_; +template <class _Fn, class... _Args> + requires __minvocable<_Fn> +struct __mdefer_<_Fn, _Args...> {}; +template <class = __q> struct __mtransform { + template <class> using __f = int; +}; +struct __completion_domain_or_none_ : __mdefer_<__mtransform<>> {}; + +} + +namespace case2 { + +template<auto& Q, class P> concept C = Q.template operator()<P>(); +template<class P> concept E = C<[]<class Ty>{ return false; }, P>; +static_assert(!E<int>); + +} + + +namespace case3 { +template <class> constexpr bool is_move_constructible_v = false; + +template <class _Tp> +concept __cpp17_move_constructible = is_move_constructible_v<_Tp>; // #is_move_constructible_v + +template <class _Tp> +concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp>; // #__cpp17_move_constructible + +template <class _Iter> +concept __cpp17_iterator = __cpp17_copy_constructible<_Iter>; // #__cpp17_copy_constructible + +struct not_move_constructible {}; +static_assert(__cpp17_iterator<not_move_constructible>); \ +// expected-error {{static assertion failed}} \ +// expected-note {{because 'not_move_constructible' does not satisfy '__cpp17_iterator'}} \ +// expected-note@#__cpp17_copy_constructible {{because 'not_move_constructible' does not satisfy '__cpp17_copy_constructible'}} \ +// expected-note@#__cpp17_move_constructible {{because 'parameter_mapping_regressions::case3::not_move_constructible' does not satisfy '__cpp17_move_constructible'}} \ +// expected-note@#is_move_constructible_v {{because 'is_move_constructible_v<parameter_mapping_regressions::case3::not_move_constructible>' evaluated to false}} +} + } diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp index e2b586e..9e5756f 100644 --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -574,8 +574,9 @@ static_assert(x.size == 4); // CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'U (&)[3]' // CHECK-NEXT: | `-ConceptSpecializationExpr 0x{{.+}} <col:36, col:42> 'bool' Concept 0x{{.+}} 'True' // CHECK-NEXT: | |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28 -// CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-0-0' -// CHECK-NEXT: | | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0 +// CHECK-NEXT: | | `-TemplateArgument type 'T' +// CHECK-NEXT: | | `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0 +// CHECK-NEXT: | | `-TemplateTypeParm 0x{{.+}} 'T' // CHECK-NEXT: | `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0' // CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0 // CHECK-NEXT: | `-TemplateTypeParm 0x{{.+}} 'T' @@ -588,8 +589,9 @@ static_assert(x.size == 4); // CHECK-NEXT: |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'double (&)[3]' // CHECK-NEXT: `-ConceptSpecializationExpr 0x{{.+}} <col:36, col:42> 'bool' Concept 0x{{.+}} 'True' // CHECK-NEXT: |-ImplicitConceptSpecializationDecl 0x{{.+}} <{{.+}}> col:28 -// CHECK-NEXT: | `-TemplateArgument type 'type-parameter-0-0' -// CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0 +// CHECK-NEXT: | `-TemplateArgument type 'T' +// CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0 +// CHECK-NEXT: | `-TemplateTypeParm 0x{{.+}} 'T' // CHECK-NEXT: `-TemplateArgument <{{.+}}> type 'T':'type-parameter-0-0' // CHECK-NEXT: `-TemplateTypeParmType 0x{{.+}} 'T' dependent depth 0 index 0 // CHECK-NEXT: `-TemplateTypeParm 0x{{.+}} 'T' @@ -660,8 +662,9 @@ Test test(42); // CHECK-NEXT: |-TemplateTypeParmDecl {{.*}} Concept {{.*}} 'Constraint' depth 0 index 1 auto:1 // CHECK-NEXT: | `-ConceptSpecializationExpr {{.*}} 'bool' Concept {{.*}} 'Constraint' // CHECK-NEXT: | |-ImplicitConceptSpecializationDecl {{.*}} -// CHECK-NEXT: | | |-TemplateArgument type 'type-parameter-0-1' -// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-1' dependent depth 0 index 1 +// CHECK-NEXT: | | |-TemplateArgument type 'auto:1' +// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'auto:1' dependent depth 0 index 1 +// CHECK-NEXT: | | | `-TemplateTypeParm {{.*}} 'auto:1' // CHECK-NEXT: | | `-TemplateArgument type 'int' // CHECK-NEXT: | | `-BuiltinType {{.*}} 'int' // CHECK-NEXT: | |-TemplateArgument {{.*}} type 'auto:1':'type-parameter-0-1' diff --git a/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp b/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp index 1f2171a..e03756e 100644 --- a/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp +++ b/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify + template<typename...> concept C = false; // expected-note 9{{because}} diff --git a/clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp b/clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp index 3edf243..de4a484 100644 --- a/clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp +++ b/clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp @@ -7,8 +7,7 @@ template<typename T> constexpr bool is_same_v<T, T> = true; template<typename T, typename U> -concept same_as = is_same_v<T, U>; -// expected-note@-1{{because 'is_same_v<int, bool>' evaluated to false}} +concept same_as = is_same_v<T, U>; //#is_same_v template<typename T, typename... Us> concept either = (is_same_v<T, Us> || ...); @@ -17,6 +16,7 @@ template<typename... Ts> struct T { template<same_as<Ts>... Us> // expected-note@-1{{because 'same_as<int, bool>' evaluated to false}} + // expected-note@#is_same_v{{because 'is_same_v<int, bool>' evaluated to false}} static void foo(Us... u, int x) { }; // expected-note@-1{{candidate template ignored: deduced too few arguments}} // expected-note@-2{{candidate template ignored: constraints not satisfied}} diff --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp index e60f792..32ad537 100644 --- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp +++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp @@ -72,12 +72,12 @@ namespace type_requirement { template<typename T> requires false_v<requires { typename T::template temp<T>; }> - // expected-note@-1 {{because 'false_v<requires { typename type_requirement::contains_template<int>::template temp<type_requirement::contains_template<int>>; }>' evaluated to false}} - // expected-note@-2 {{because 'false_v<requires { typename type_requirement::contains_template<short>::template temp<type_requirement::contains_template<short>>; }>' evaluated to false}} + // expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::template temp<contains_template<int>>; }>' evaluated to false}} + // expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::template temp<contains_template<short>>; }>' evaluated to false}} struct r2 {}; - using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}} - using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<short>]}} + using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template<int>]}} + using r2i2 = r2<contains_template<short>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = contains_template<short>]}} // substitution error occurs, then requires expr is instantiated again @@ -108,7 +108,7 @@ namespace type_requirement { // expected-note@-1 {{because 'false_v<requires { <<error-type>>; } && requires { <<error-type>>; }>' evaluated to false}} struct r7 {}; - using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, type_requirement::A>]}} + using r7i = r7<int, A>; // expected-error{{constraints not satisfied for class template 'r7' [with Ts = <int, A>]}} } namespace expr_requirement { @@ -268,3 +268,13 @@ struct Foo { }; } // namespace GH110785 + +namespace sugared_instantiation { + template <class C1> concept C = requires { C1{}; }; + template <class D1> concept D = requires { new D1; }; + + // Test that 'deduced auto' doesn't get confused with 'undeduced auto'. + auto f() { return 0; } + static_assert(requires { { f() } -> C; }); + static_assert(requires { { f() } -> D; }); +} // namespace sugared_instantiation diff --git a/clang/test/SemaTemplate/instantiate-template-argument.cpp b/clang/test/SemaTemplate/instantiate-template-argument.cpp index 43d5d00..7606619 100644 --- a/clang/test/SemaTemplate/instantiate-template-argument.cpp +++ b/clang/test/SemaTemplate/instantiate-template-argument.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify +// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify=expected,cxx20 +// RUN: %clang_cc1 -std=c++2c -x c++ %s -verify + template<auto T, decltype(T) U> concept C1 = sizeof(U) >= 4; @@ -9,20 +11,101 @@ concept C2 = C1<Y{}, V>; // sizeof(U) >= 4 [U = V (decltype(Y{}))] template<char W> -constexpr int foo() requires C2<int, W> { return 1; } +constexpr int foo() requires C2<int, W> { return 1; } // #cand1 // sizeof(U) >= 4 [U = W (decltype(int{}))] template<char X> -// expected-note@+1{{candidate function}} -constexpr int foo() requires C1<1, X> && true { return 2; } +constexpr int foo() requires C1<1, X> && true { return 2; } // #cand2 // sizeof(U) >= 4 [U = X (decltype(1))] static_assert(foo<'a'>() == 2); + template<char Z> -// expected-note@+1{{candidate function}} -constexpr int foo() requires C2<long long, Z> && true { return 3; } +constexpr int foo() requires C2<long long, Z> && true { return 3; } // #cand3 // sizeof(U) >= 4 [U = Z (decltype(long long{}))] static_assert(foo<'a'>() == 3); -// expected-error@-1{{call to 'foo' is ambiguous}}
\ No newline at end of file +// expected-error@-1{{call to 'foo' is ambiguous}} +// expected-note@#cand2 {{candidate function}} +// expected-note@#cand3 {{candidate function}} + + +namespace case1 { + +template<auto T, decltype(T) U> +concept C1 = sizeof(T) >= 4; // #case1_C1 + +template<typename Y, char V> +concept C2 = C1<Y{}, V>; // #case1_C2 + +template<class T, char W> +constexpr int foo() requires C2<T, W> { return 1; } // #case1_foo1 + +template<class T, char X> +constexpr int foo() requires C1<T{}, X> && true { return 2; } // #case1_foo2 + +static_assert(foo<char, 'a'>() == 2); +// expected-error@-1{{no matching function for call to 'foo'}} +// expected-note@#case1_foo1{{candidate template ignored: constraints not satisfied [with T = char, W = 'a']}} +// expected-note@#case1_foo1{{because 'C2<char, 'a'>' evaluated to false}} +// expected-note@#case1_C2{{because 'C1<char{}, 'a'>' evaluated to false}} +// expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}} +// expected-note@#case1_foo2{{candidate template ignored: constraints not satisfied [with T = char, X = 'a']}} +// expected-note@#case1_foo2{{because 'C1<char{}, 'a'>' evaluated to false}} +// expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}} + +static_assert(foo<int, 'a'>() == 2); + +} + +namespace packs { + +template<auto T, decltype(T) U> +concept C1 = sizeof(U) >= 4; + +template<typename Y, char V> +concept C2 = C1<Y{}, V>; + +template<char... W> +constexpr int foo() requires (C2<int, W> && ...) { return 1; } // #packs-cand1 + +template<char... X> +constexpr int foo() requires (C1<1, X> && ...) && true { return 2; } // #packs-cand2 + +static_assert(foo<'a'>() == 2); +// cxx20-error@-1{{call to 'foo' is ambiguous}} +// cxx20-note@#packs-cand1 {{candidate function}} +// cxx20-note@#packs-cand2 {{candidate function}} + +} + +namespace case2 { +template<auto T> concept C1 = sizeof(decltype(T)) >= 0; +template<typename Y> concept C2 = C1<Y{}>; + +template<char W> +constexpr int foo() requires C2<int> { return 1; } + +template<char X> +constexpr int foo() requires C1<0> && true { return 2; } + +static_assert(foo<0>() == 2); +} + +namespace case3 { +template<auto T> concept C1 = sizeof(decltype(T)) >= 0; + +template<typename Y> concept C2 = C1<Y{}>; + +template<char W> +constexpr int foo() requires C2<int> { return 1; } // #case3_foo1 + +template<char X> +constexpr int foo() requires C1<1> && true { return 2; } // #case3_foo2 + +static_assert(foo<0>() == 2); +// expected-error@-1{{call to 'foo' is ambiguous}} +// expected-note@#case3_foo1 {{candidate function}} +// expected-note@#case3_foo2 {{candidate function}} +} diff --git a/clang/test/SemaTemplate/pr52970.cpp b/clang/test/SemaTemplate/pr52970.cpp index 7aac5ee..6aabc41 100644 --- a/clang/test/SemaTemplate/pr52970.cpp +++ b/clang/test/SemaTemplate/pr52970.cpp @@ -53,7 +53,7 @@ static_assert(!DotFollowingPointer::f(Bad{}), ""); #if __cplusplus >= 202002L template <class T> concept C = requires(T t) { t.begin(); }; - // cxx20-note@-1 {{because 't.begin()' would be invalid: member reference type 'Holder<Incomplete> *' is a pointer}} + // cxx20-note@-1 {{because 't.begin()' would be invalid: member reference type 'Bad' (aka 'Holder<Incomplete> *') is a pointer}} static_assert(C<Good>); static_assert(!C<Bad>); |