262 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2template<typename T, typename U> constexpr bool is_same_v = false;3template<typename T> constexpr bool is_same_v<T, T> = true;4 5template<typename... T>6struct type_list;7 8namespace unconstrained {9 decltype(auto) f1(auto x) { return x; }10 static_assert(is_same_v<decltype(f1(1)), int>);11 static_assert(is_same_v<decltype(f1('c')), char>);12 13 decltype(auto) f2(auto &x) { return x; }14 // expected-note@-1{{candidate function [with x:auto = int] not viable: expects an lvalue for 1st argument}}15 // expected-note@-2{{candidate function [with x:auto = char] not viable: expects an lvalue for 1st argument}}16 static_assert(is_same_v<decltype(f2(1)), int &>); // expected-error{{no matching}}17 static_assert(is_same_v<decltype(f2('c')), char &>); // expected-error{{no matching}}18 19 decltype(auto) f3(const auto &x) { return x; }20 static_assert(is_same_v<decltype(f3(1)), const int &>);21 static_assert(is_same_v<decltype(f3('c')), const char &>);22 23 decltype(auto) f4(auto (*x)(auto y)) { return x; } // expected-error{{'auto' not allowed in function prototype}}24 25 decltype(auto) f5(void (*x)(decltype(auto) y)) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}}26 27 int return_int(); void return_void(); int foo(int);28 29 decltype(auto) f6(auto (*x)()) { return x; }30 // expected-note@-1{{candidate template ignored: failed template argument deduction}}31 static_assert(is_same_v<decltype(f6(return_int)), int (*)()>);32 static_assert(is_same_v<decltype(f6(return_void)), void (*)()>);33 using f6c1 = decltype(f6(foo)); // expected-error{{no matching}}34 35 decltype(auto) f7(auto (*x)() -> int) { return x; }36 // expected-note@-1{{candidate function not viable: no known conversion from 'void ()' to 'auto (*)() -> int' for 1st argument}}37 // expected-note@-2{{candidate function not viable: no known conversion from 'int (int)' to 'auto (*)() -> int' for 1st argument}}38 static_assert(is_same_v<decltype(f7(return_int)), int (*)()>);39 using f7c1 = decltype(f7(return_void)); // expected-error{{no matching}}40 using f7c2 = decltype(f7(foo)); // expected-error{{no matching}}41 static_assert(is_same_v<decltype(&f7), int (*(*)(int (*x)()))()>);42 43 decltype(auto) f8(auto... x) { return (x + ...); }44 static_assert(is_same_v<decltype(f8(1, 2, 3)), int>);45 static_assert(is_same_v<decltype(f8('c', 'd')), int>);46 static_assert(is_same_v<decltype(f8('c', 1)), int>);47 48 decltype(auto) f9(auto &... x) { return (x, ...); }49 // expected-note@-1{{candidate function [with x:auto = <int (), int>] not viable: expects an lvalue for 2nd argument}}50 using f9c1 = decltype(f9(return_int, 1)); // expected-error{{no matching}}51 52 decltype(auto) f11(decltype(auto) x) { return x; } // expected-error{{'decltype(auto)' not allowed in function prototype}}53 54 template<typename T>55 auto f12(auto x, T y) -> type_list<T, decltype(x)>;56 static_assert(is_same_v<decltype(f12(1, 'c')), type_list<char, int>>);57 static_assert(is_same_v<decltype(f12<char>(1, 'c')), type_list<char, int>>);58 59 template<typename T>60 auto f13(T x, auto y) -> type_list<T, decltype(y)>;61 static_assert(is_same_v<decltype(f13(1, 'c')), type_list<int, char>>);62 static_assert(is_same_v<decltype(f13<char>(1, 'c')), type_list<char, char>>);63 64 template<typename T>65 auto f14(auto y) -> type_list<T, decltype(y)>;66 static_assert(is_same_v<decltype(f14<int>('c')), type_list<int, char>>);67 static_assert(is_same_v<decltype(f14<int, char>('c')), type_list<int, char>>);68 69 template<typename T, typename U>70 auto f15(auto y, U u) -> type_list<T, U, decltype(y)>;71 static_assert(is_same_v<decltype(f15<int>('c', nullptr)), type_list<int, decltype(nullptr), char>>);72 static_assert(is_same_v<decltype(f15<int, decltype(nullptr)>('c', nullptr)), type_list<int, decltype(nullptr), char>>);73 74 auto f16(auto x, auto y) -> type_list<decltype(x), decltype(y)>;75 static_assert(is_same_v<decltype(f16('c', 1)), type_list<char, int>>);76 static_assert(is_same_v<decltype(f16<int>('c', 1)), type_list<int, int>>);77 static_assert(is_same_v<decltype(f16<int, char>('c', 1)), type_list<int, char>>);78 79 void f17(auto x, auto y) requires (sizeof(x) > 1);80 // expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = char, y:auto = int]}}81 // expected-note@-2{{because 'sizeof (x) > 1' (1 > 1) evaluated to false}}82 static_assert(is_same_v<decltype(f17('c', 1)), void>);83 // expected-error@-1{{no matching}}84 static_assert(is_same_v<decltype(f17<int>('c', 1)), void>);85 static_assert(is_same_v<decltype(f17<int, char>('c', 1)), void>);86 87 void f18(auto... x) requires (sizeof...(x) == 2);88 // expected-note@-1{{candidate template ignored: constraints not satisfied [with x:auto = <char, int, int>]}}89 // expected-note@-2{{candidate template ignored: constraints not satisfied [with x:auto = <char>]}}90 // expected-note@-3{{because 'sizeof...(x) == 2' (1 == 2) evaluated to false}}91 // expected-note@-4{{because 'sizeof...(x) == 2' (3 == 2) evaluated to false}}92 static_assert(is_same_v<decltype(f18('c')), void>);93 // expected-error@-1{{no matching}}94 static_assert(is_same_v<decltype(f18('c', 1)), void>);95 static_assert(is_same_v<decltype(f18('c', 1, 2)), void>);96 // expected-error@-1{{no matching}}97 98 template<typename T>99 struct S { // #defined-here100 constexpr auto f1(auto x, T t) -> decltype(x + t);101 102 template<typename U>103 constexpr auto f2(U u, auto x, T t) -> decltype(x + u + t);104 };105 106 template<typename T>107 constexpr auto S<T>::f1(auto x, T t) -> decltype(x + t) { return x + t; }108 109 template<typename T>110 template<typename U>111 constexpr auto S<T>::f2(auto x, U u, T t) -> decltype(x + u + t) { return x + u + t; }112 // expected-error@-1 {{out-of-line definition of 'f2' does not match any declaration in 'unconstrained::S<T>'}}113 // expected-note@#defined-here {{S defined here}}114 115 template<typename T>116 template<typename U>117 constexpr auto S<T>::f2(U u, auto x, T t) -> decltype(x + u + t) { return x + u + t; }118 119 template<>120 template<>121 constexpr auto S<int>::f2<double>(double u, char x, int t) -> double { return 42; }122 123 static_assert(S<char>{}.f1(1, 2) == 3);124 static_assert(S<char>{}.f2(1, 2, '\x00') == 3);125 static_assert(S<char>{}.f2<double>(1, 2, '\x00') == 3.);126 static_assert(S<int>{}.f2<double>(1, '2', '\x00') == 42);127}128 129namespace constrained {130 template<typename T>131 concept C = is_same_v<T, int>;132 // expected-note@-1 12{{because}}133 template<typename T, typename U>134 concept C2 = is_same_v<T, U>;135 // expected-note@-1 12{{because}}136 137 int i;138 const int ci = 1;139 char c;140 const char cc = 'a';141 int g(int);142 char h(int);143 144 void f1(C auto x);145 // expected-note@-1 {{candidate template ignored: constraints not satisfied [with x:auto = }}146 // expected-note@-2{{because}}147 static_assert(is_same_v<decltype(f1(1)), void>);148 static_assert(is_same_v<decltype(f1('a')), void>);149 // expected-error@-1{{no matching}}150 void f2(C auto &x);151 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}152 static_assert(is_same_v<decltype(f2(i)), void>);153 static_assert(is_same_v<decltype(f2(ci)), void>);154 // expected-error@-1{{no matching}}155 static_assert(is_same_v<decltype(f2(c)), void>);156 // expected-error@-1{{no matching}}157 void f3(const C auto &x);158 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}159 static_assert(is_same_v<decltype(f3(i)), void>);160 static_assert(is_same_v<decltype(f3(ci)), void>);161 static_assert(is_same_v<decltype(f3(c)), void>);162 // expected-error@-1{{no matching}}163 void f4(C auto (*x)(C auto y)); // expected-error{{'auto' not allowed}}164 void f5(C auto (*x)(int y));165 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}166 static_assert(is_same_v<decltype(f5(g)), void>);167 static_assert(is_same_v<decltype(f5(h)), void>);168 // expected-error@-1{{no matching}}169 void f6(C auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C auto'}}170 void f7(C auto... x);171 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}172 static_assert(is_same_v<decltype(f7(1, 2)), void>);173 static_assert(is_same_v<decltype(f7(1, 'a')), void>);174 // expected-error@-1{{no matching}}175 static_assert(is_same_v<decltype(f7('a', 2)), void>);176 // expected-error@-1{{no matching}}177 void f8(C auto &... x);178 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}179 static_assert(is_same_v<decltype(f8(i, i)), void>);180 static_assert(is_same_v<decltype(f8(i, c)), void>);181 // expected-error@-1{{no matching}}182 static_assert(is_same_v<decltype(f8(i, i, ci)), void>);183 // expected-error@-1{{no matching}}184 void f9(const C auto &... x);185 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}186 static_assert(is_same_v<decltype(f9(i, i)), void>);187 static_assert(is_same_v<decltype(f9(i, c)), void>);188 // expected-error@-1{{no matching}}189 static_assert(is_same_v<decltype(f9(i, i, ci)), void>);190 void f10(C decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}191 auto f11 = [] (C auto x) { };192 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}193 static_assert(is_same_v<decltype(f11(1)), void>);194 static_assert(is_same_v<decltype(f11('a')), void>);195 // expected-error@-1{{no matching}}196 197 void f12(C2<char> auto x);198 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}199 static_assert(is_same_v<decltype(f12(1)), void>);200 // expected-error@-1{{no matching}}201 static_assert(is_same_v<decltype(f12('a')), void>);202 void f13(C2<char> auto &x);203 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}204 static_assert(is_same_v<decltype(f13(i)), void>);205 // expected-error@-1{{no matching}}206 static_assert(is_same_v<decltype(f13(cc)), void>);207 // expected-error@-1{{no matching}}208 static_assert(is_same_v<decltype(f13(c)), void>);209 void f14(const C2<char> auto &x);210 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}211 static_assert(is_same_v<decltype(f14(i)), void>);212 // expected-error@-1{{no matching}}213 static_assert(is_same_v<decltype(f14(cc)), void>);214 static_assert(is_same_v<decltype(f14(c)), void>);215 void f15(C2<char> auto (*x)(C2<int> auto y)); // expected-error{{'auto' not allowed}}216 void f16(C2<char> auto (*x)(int y));217 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}218 static_assert(is_same_v<decltype(f16(g)), void>);219 // expected-error@-1{{no matching}}220 static_assert(is_same_v<decltype(f16(h)), void>);221 void f17(C2<char> auto (*x)() -> int); // expected-error{{function with trailing return type must specify return type 'auto', not 'C2<char> auto'}}222 void f18(C2<char> auto... x);223 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}224 static_assert(is_same_v<decltype(f18('a', 'b')), void>);225 static_assert(is_same_v<decltype(f18('a', 1)), void>);226 // expected-error@-1{{no matching}}227 static_assert(is_same_v<decltype(f18(2, 'a')), void>);228 // expected-error@-1{{no matching}}229 void f19(C2<char> auto &... x);230 // expected-note@-1 2{{candidate template ignored}} expected-note@-1 2{{because}}231 static_assert(is_same_v<decltype(f19(c, c)), void>);232 static_assert(is_same_v<decltype(f19(i, c)), void>);233 // expected-error@-1{{no matching}}234 static_assert(is_same_v<decltype(f19(c, c, cc)), void>);235 // expected-error@-1{{no matching}}236 void f20(const C2<char> auto &... x);237 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}238 static_assert(is_same_v<decltype(f20(c, c)), void>);239 static_assert(is_same_v<decltype(f20(i, c)), void>);240 // expected-error@-1{{no matching}}241 static_assert(is_same_v<decltype(f20(c, c, cc)), void>);242 void f21(C2<char> decltype(auto) x); // expected-error{{decltype(auto)' not allowed in function prototype}}243 auto f22 = [] (C2<char> auto x) { };244 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}245 static_assert(is_same_v<decltype(f22(1)), void>);246 // expected-error@-1{{no matching}}247 static_assert(is_same_v<decltype(f22('a')), void>);248 249 struct S1 { S1(C auto); };250 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}251 // expected-note@-2 2{{candidate constructor}}252 static_assert(is_same_v<decltype(S1(1)), S1>);253 static_assert(is_same_v<decltype(S1('a')), S1>);254 // expected-error@-1{{no matching}}255 struct S2 { S2(C2<char> auto); };256 // expected-note@-1{{candidate template ignored}} expected-note@-1{{because}}257 // expected-note@-2 2{{candidate constructor}}258 static_assert(is_same_v<decltype(S2(1)), S2>);259 // expected-error@-1{{no matching}}260 static_assert(is_same_v<decltype(S2('a')), S2>);261}262