xref: /llvm-project/clang/test/SemaTemplate/cxx2a-constraint-exprs.cpp (revision e0cdafe8d4b2f1585f4756447b677fec37954ec4)
1 // RUN:  %clang_cc1 -std=c++2a -verify %s
2 
3 // Make sure constraint expressions are unevaluated before being substituted
4 // into during satisfaction checking.
5 
6 template<typename T> constexpr bool f = T::value;
7 // expected-error@-1 4{{type}}
8 
9 namespace unevaluated {
10   template<typename T> concept Foo = false && f<int>;
11   bool k = Foo<int>;
12   template<typename T> requires false && f<int> struct S {};
13   // expected-note@-1{{because}}
14   using s = S<int>; // expected-error {{constraints not satisfied}}
foo()15   template<typename T> void foo() requires false && f<int> { };
16   // expected-note@-1{{because}} expected-note@-1{{candidate template ignored}}
17   int a = (foo<int>(), 0); // expected-error{{no matching function}}
bar()18   template<typename T> void bar() requires requires { requires false && f<int>; } { };
19   // expected-note@-1{{because}} expected-note@-1{{candidate template ignored}}
20   int b = (bar<int>(), 0); // expected-error{{no matching function}}
foounevaluated::M21   template<typename T> struct M { static void foo() requires false && f<int> { }; };
22   // expected-note@-1{{because}}
23   int c = (M<int>::foo(), 0);
24   // expected-error@-1{{invalid reference to function 'foo': constraints not satisfied}}
25 }
26 
27 namespace constant_evaluated {
28   template<typename T> requires f<int[0]> struct S {};
29   // expected-note@-1{{in instantiation of}} expected-note@-1{{while substituting}}
30   using s = S<int>;
31   // expected-note@-1 {{while checking}}
foo()32   template<typename T> void foo() requires f<int[1]> { };
33   // expected-note@-1{{in instantiation}} expected-note@-1{{while substituting}} \
34      expected-note@-1{{candidate template ignored}}
35   int a = (foo<int>(), 0);
36   // expected-note@-1 {{while checking}} expected-error@-1{{no matching function}} \
37      expected-note@-1 {{in instantiation}}
bar()38   template<typename T> void bar() requires requires { requires f<int[2]>; } { };
39   // expected-note@-1{{in instantiation}} \
40      expected-note@-1{{while substituting}} \
41      expected-note@-1 {{while checking the satisfaction of nested requirement}}
42   int b = (bar<int>(), 0);
fooconstant_evaluated::M43   template<typename T> struct M { static void foo() requires f<int[3]> { }; };
44   // expected-note@-1{{in instantiation}} expected-note@-1{{while substituting}}
45   int c = (M<int>::foo(), 0);
46   // expected-note@-1 {{while checking}}
47 }
48