112 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify=expected,cxx202// RUN: %clang_cc1 -std=c++2c -x c++ %s -verify3 4 5template<auto T, decltype(T) U>6concept C1 = sizeof(U) >= 4;7// sizeof(U) >= 4 [U = U (decltype(T))]8 9template<typename Y, char V>10concept C2 = C1<Y{}, V>;11// sizeof(U) >= 4 [U = V (decltype(Y{}))]12 13template<char W>14constexpr int foo() requires C2<int, W> { return 1; } // #cand115// sizeof(U) >= 4 [U = W (decltype(int{}))]16 17template<char X>18constexpr int foo() requires C1<1, X> && true { return 2; } // #cand219// sizeof(U) >= 4 [U = X (decltype(1))]20 21static_assert(foo<'a'>() == 2);22 23 24template<char Z>25constexpr int foo() requires C2<long long, Z> && true { return 3; } // #cand326// sizeof(U) >= 4 [U = Z (decltype(long long{}))]27 28static_assert(foo<'a'>() == 3);29// expected-error@-1{{call to 'foo' is ambiguous}}30// expected-note@#cand2 {{candidate function}}31// expected-note@#cand3 {{candidate function}}32 33 34namespace case1 {35 36template<auto T, decltype(T) U>37concept C1 = sizeof(T) >= 4; // #case1_C138 39template<typename Y, char V>40concept C2 = C1<Y{}, V>; // #case1_C241 42template<class T, char W>43constexpr int foo() requires C2<T, W> { return 1; } // #case1_foo144 45template<class T, char X>46constexpr int foo() requires C1<T{}, X> && true { return 2; } // #case1_foo247 48static_assert(foo<char, 'a'>() == 2);49// expected-error@-1{{no matching function for call to 'foo'}}50// expected-note@#case1_foo1{{candidate template ignored: constraints not satisfied [with T = char, W = 'a']}}51// expected-note@#case1_foo1{{because 'C2<char, 'a'>' evaluated to false}}52// expected-note@#case1_C2{{because 'C1<char{}, 'a'>' evaluated to false}}53// expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}}54// expected-note@#case1_foo2{{candidate template ignored: constraints not satisfied [with T = char, X = 'a']}}55// expected-note@#case1_foo2{{because 'C1<char{}, 'a'>' evaluated to false}}56// expected-note@#case1_C1{{because 'sizeof ('\x00') >= 4' (1 >= 4) evaluated to false}}57 58static_assert(foo<int, 'a'>() == 2);59 60}61 62namespace packs {63 64template<auto T, decltype(T) U>65concept C1 = sizeof(U) >= 4;66 67template<typename Y, char V>68concept C2 = C1<Y{}, V>;69 70template<char... W>71constexpr int foo() requires (C2<int, W> && ...) { return 1; } // #packs-cand172 73template<char... X>74constexpr int foo() requires (C1<1, X> && ...) && true { return 2; } // #packs-cand275 76static_assert(foo<'a'>() == 2);77// cxx20-error@-1{{call to 'foo' is ambiguous}}78// cxx20-note@#packs-cand1 {{candidate function}}79// cxx20-note@#packs-cand2 {{candidate function}}80 81}82 83namespace case2 {84template<auto T> concept C1 = sizeof(decltype(T)) >= 0;85template<typename Y> concept C2 = C1<Y{}>;86 87template<char W>88constexpr int foo() requires C2<int> { return 1; }89 90template<char X>91constexpr int foo() requires C1<0> && true { return 2; }92 93static_assert(foo<0>() == 2);94}95 96namespace case3 {97template<auto T> concept C1 = sizeof(decltype(T)) >= 0;98 99template<typename Y> concept C2 = C1<Y{}>;100 101template<char W>102constexpr int foo() requires C2<int> { return 1; } // #case3_foo1103 104template<char X>105constexpr int foo() requires C1<1> && true { return 2; } // #case3_foo2106 107static_assert(foo<0>() == 2);108// expected-error@-1{{call to 'foo' is ambiguous}}109// expected-note@#case3_foo1 {{candidate function}}110// expected-note@#case3_foo2 {{candidate function}}111}112