xref: /llvm-project/clang/test/CXX/drs/cwg26xx.cpp (revision b46fcb9fa32f24660b1b8858d5c4cbdb76ef9d8b)
1 // RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98
2 // RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,since-cxx11,cxx11
3 // RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,since-cxx11
4 // RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx11
5 // RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx11,since-cxx20
6 // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx11,since-cxx20,since-cxx23
7 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx11,since-cxx20,since-cxx23
8 
9 #if __cplusplus == 199711L
10 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
11 // cxx98-error@-1 {{variadic macros are a C99 feature}}
12 #endif
13 
14 namespace std {
15 #if __cplusplus >= 202002L
16   struct strong_ordering {
17     int n;
18     constexpr operator int() const { return n; }
19     static const strong_ordering less, equal, greater;
20   };
21   constexpr strong_ordering strong_ordering::less{-1},
22       strong_ordering::equal{0}, strong_ordering::greater{1};
23 #endif
24 
25   typedef short int16_t;
26   typedef unsigned short uint16_t;
27   typedef int int32_t;
28   typedef unsigned uint32_t;
29   typedef long long int64_t;
30   // cxx98-error@-1 {{'long long' is a C++11 extension}}
31   typedef unsigned long long uint64_t;
32   // cxx98-error@-1 {{'long long' is a C++11 extension}}
33   static_assert(sizeof(int16_t) == 2 && sizeof(int32_t) == 4 && sizeof(int64_t) == 8, "Some tests rely on these sizes");
34 
35   template<typename T> T declval();
36 } // namespace std
37 
38 namespace cwg2621 { // cwg2621: sup 2877
39 #if __cplusplus >= 202002L
40 enum class E { a };
41 namespace One {
42 using E_t = E;
43 using enum E_t; // typedef ok
44 auto v = a;
45 }
46 namespace Two {
47 using cwg2621::E;
48 int E; // ignored by type-only lookup
49 using enum E;
50 }
51 #endif
52 } // namespace cwg2621
53 
54 namespace cwg2627 { // cwg2627: 20
55 #if __cplusplus >= 202002L
56 struct C {
57   long long i : 8;
58   friend auto operator<=>(C, C) = default;
59 };
60 
61 void f() {
62   C x{1}, y{2};
63   static_cast<void>(x <=> y);
64   static_cast<void>(x.i <=> y.i);
65 }
66 
67 template<typename T>
68 struct CDependent {
69   T i : 8;
70   friend auto operator<=>(CDependent, CDependent) = default;
71 };
72 
73 template<typename T>
74 concept three_way_comparable = requires(T t) { { t <=> t }; };
75 template<typename T>
76 concept bf_three_way_comparable = requires(T t) { { t.i <=> t.i }; };
77 static_assert(three_way_comparable<CDependent<long long>>);
78 static_assert(bf_three_way_comparable<CDependent<long long>>);
79 #endif
80 
81 #if __cplusplus >= 201103L
82 template<typename T, int N>
83 struct D {
84   T i : N;
85 };
86 
87 template<typename T, int N>
88 D<T, N> d();
89 
90 std::int32_t d1{ d<std::int64_t, 31>().i };
91 std::int32_t d2{ d<std::int64_t, 32>().i };
92 std::int32_t d3{ d<std::int64_t, 33>().i };
93 // since-cxx11-error@-1 {{non-constant-expression cannot be narrowed from type 'long long' to 'std::int32_t' (aka 'int') in initializer list}}
94 //   since-cxx11-note@-2 {{insert an explicit cast to silence this issue}}
95 
96 std::int16_t d6{ d<int, 16>().i };
97 std::int16_t d7{ d<unsigned, 15>().i };
98 std::int16_t d8{ d<unsigned, 16>().i };
99 // since-cxx11-error@-1 {{non-constant-expression cannot be narrowed from type 'unsigned int' to 'std::int16_t' (aka 'short') in initializer list}}
100 //   since-cxx11-note@-2 {{insert an explicit cast to silence this issue}}
101 std::uint16_t d9{ d<unsigned, 16>().i };
102 std::uint16_t da{ d<int, 1>().i };
103 // since-cxx11-error@-1 {{non-constant-expression cannot be narrowed from type 'int' to 'std::uint16_t' (aka 'unsigned short') in initializer list}}
104 //   since-cxx11-note@-2 {{insert an explicit cast to silence this issue}}
105 
106 bool db{ d<unsigned, 1>().i };
107 bool dc{ d<int, 1>().i };
108 // since-cxx11-error@-1 {{non-constant-expression cannot be narrowed from type 'int' to 'bool' in initializer list}}
109 //   since-cxx11-note@-2 {{insert an explicit cast to silence this issue}}
110 
111 template<typename Target, typename Source>
112 constexpr decltype(Target{ std::declval<Source>().i }, false) is_narrowing(int) { return false; }
113 template<typename Target, typename Source>
114 constexpr bool is_narrowing(long) { return true; }
115 
116 static_assert(!is_narrowing<std::int16_t, D<int, 16>>(0), "");
117 static_assert(!is_narrowing<std::int16_t, D<unsigned, 15>>(0), "");
118 static_assert(is_narrowing<std::int16_t, D<unsigned, 16>>(0), "");
119 static_assert(!is_narrowing<std::uint16_t, D<unsigned, 16>>(0), "");
120 static_assert(is_narrowing<std::uint16_t, D<int, 1>>(0), "");
121 static_assert(!is_narrowing<bool, D<unsigned, 1>>(0), "");
122 static_assert(is_narrowing<bool, D<int, 1>>(0), "");
123 
124 template<int N>
125 struct E {
126   signed int x : N;
127   decltype(std::int16_t{ x }) dependent_narrowing;
128   decltype(unsigned{ x }) always_narrowing;
129   // since-cxx11-error@-1 {{non-constant-expression cannot be narrowed from type 'int' to 'unsigned int' in initializer list}}
130   //   since-cxx11-note@-2 {{insert an explicit cast to silence this issue}}
131 };
132 #endif
133 } // namespace cwg2627
134 
135 namespace cwg2628 { // cwg2628: 20
136 #if __cplusplus >= 202002L
137 template <bool A = false, bool B = false>
138 struct foo {
139   constexpr foo() requires (!A && !B) = delete; // #cwg2628-ctor
140   constexpr foo() requires (A || B) = delete;
141 };
142 
143 void f() {
144   foo fooable; // #cwg2628-fooable
145   // since-cxx20-error@#cwg2628-fooable {{call to deleted}}
146   //   since-cxx20-note@#cwg2628-ctor {{marked deleted here}}
147 }
148 #endif
149 } // namespace cwg2628
150 
151 // cwg2630 is in cwg2630.cpp
152 
153 namespace cwg2631 { // cwg2631: 16
154 #if __cplusplus >= 202002L
155   constexpr int g();
156   consteval int f() {
157     return g();
158   }
159   int k(int x = f()) {
160     return x;
161   }
162   constexpr int g() {
163     return 42;
164   }
165   int test() {
166     return k();
167   }
168 #endif
169 } // namespace cwg2631
170 
171 namespace cwg2635 { // cwg2635: 16
172 #if __cplusplus >= 202002L
173 template<typename T>
174 concept UnaryC = true;
175 template<typename T, typename U>
176 concept BinaryC = true;
177 
178 struct S{ int i, j; };
179 S get_S();
180 
181 template<typename T>
182 T get_T();
183 
184 void use() {
185   UnaryC auto [a, b] = get_S();
186   // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
187   BinaryC<int> auto [c, d] = get_S();
188   // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
189 }
190 
191 template<typename T>
192 void TemplUse() {
193   UnaryC auto [a, b] = get_T<T>();
194   // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
195   BinaryC<T> auto [c, d] = get_T<T>();
196   // since-cxx20-error@-1 {{decomposition declaration cannot be declared with constrained 'auto'}}
197 }
198 #endif
199 } // namespace cwg2635
200 
201 // cwg2636: na
202 
203 namespace cwg2640 { // cwg2640: 16
204 
205 int \N{Λ} = 0;
206 // expected-error@-1 {{'Λ' is not a valid Unicode character name}}
207 // expected-error@-2 {{expected unqualified-id}}
208 const char* emoji = "\N{��}";
209 // expected-error@-1 {{'��' is not a valid Unicode character name}}
210 //   expected-note@-2 {{did you mean OX ('��' U+1F402)?}}
211 //   expected-note@-3 {{did you mean ANT ('��' U+1F41C)?}}
212 //   expected-note@-4 {{did you mean ARC ('⌒' U+2312)?}}
213 //   expected-note@-5 {{did you mean AXE ('��' U+1FA93)?}}
214 //   expected-note@-6 {{did you mean BAT ('��' U+1F987)?}}
215 
216 #define z(x) 0
217 #define cwg2640_a z(
218 int x = cwg2640_a\N{abc});
219 // expected-error@-1 {{'abc' is not a valid Unicode character name}}
220 int y = cwg2640_a\N{LOTUS});
221 // expected-error@-1 {{character <U+1FAB7> not allowed in an identifier}}
222 // expected-error@-2 {{use of undeclared identifier 'cwg2640_a��'}}
223 // expected-error@-3 {{extraneous ')' before ';'}}
224 } // namespace cwg2640
225 
226 // cwg2642: na
227 
228 namespace cwg2644 { // cwg2644: 8
229 #if __cplusplus >= 201103L
230 auto z = [a = 42](int a) {
231 // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
232 // since-cxx11-error@-2 {{a lambda parameter cannot shadow an explicitly captured entity}}
233 //   since-cxx11-note@-3 {{variable 'a' is explicitly captured here}}
234      return 1;
235 };
236 #endif
237 } // namespace cwg2644
238 
239 namespace cwg2650 { // cwg2650: 17
240 #if __cplusplus >= 202302L
241 template <class T, T> struct S {};
242 template <class T> int f(S<T, T{}>*); // #cwg2650-f
243 class X {
244   int m;
245 };
246 int i0 = f<X>(0);
247 // since-cxx23-error@-1 {{no matching function for call to 'f'}}
248 //   since-cxx23-note@#cwg2650-f {{type 'X' of non-type template parameter is not a structural type}}
249 #endif
250 } // namespace cwg2650
251 
252 namespace cwg2653 { // cwg2653: 18
253 #if __cplusplus >= 202302L
254   struct Test { void f(this const auto& = Test{}); };
255   // since-cxx23-error@-1 {{the explicit object parameter cannot have a default argument}}
256   auto L = [](this const auto& = Test{}){};
257   // since-cxx23-error@-1 {{the explicit object parameter cannot have a default argument}}
258 #endif
259 } // namespace cwg2653
260 
261 namespace cwg2654 { // cwg2654: 16
262 void f() {
263     int neck, tail;
264     volatile int brachiosaur;
265     brachiosaur += neck;                // OK
266     brachiosaur -= neck;                // OK
267     brachiosaur |= neck;                // OK
268 }
269 } // namespace cwg2654
270 
271 namespace cwg2681 { // cwg2681: 17
272 #if __cplusplus >= 202002L
273 using size_t = decltype(sizeof(int));
274 
275 template<class T, size_t N>
276 struct H {
277   T array[N];
278 };
279 template<class T, size_t N>
280 struct I {
281   volatile T array[N];
282 };
283 template<size_t N>
284 struct J { // #cwg2681-J
285   unsigned char array[N];
286 };
287 
288 H h = { "abc" };
289 I i = { "def" };
290 static_assert(__is_same(decltype(h), H<char, 4>));  // Not H<const char, 4>
291 static_assert(__is_same(decltype(i), I<char, 4>));
292 
293 J j = { "ghi" };
294 // since-cxx20-error@-1 {{no viable constructor or deduction guide}}
295 //   since-cxx20-note@#cwg2681-J {{candidate template ignored: could not match 'J<N>' against 'const char *'}}
296 //   since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(J<N>) -> J<N>'}}
297 //   since-cxx20-note@#cwg2681-J {{candidate template ignored: could not match 'const unsigned char' against 'const char'}}
298 //   since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(const unsigned char (&)[N]) -> J<N>'}}
299 //   since-cxx20-note@#cwg2681-J {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
300 //   since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J() -> J<N>'}}
301 #endif
302 } // namespace cwg2681
303 
304 namespace cwg2672 { // cwg2672: 18
305 #if __cplusplus >= 202002L
306 template <class T>
307 void f(T) requires requires { []() { T::invalid; } (); };
308 // since-cxx20-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}}
309 //   since-cxx20-note@-2 {{while substituting into a lambda expression here}}
310 //   since-cxx20-note@-3 {{in instantiation of requirement here}}
311 //   since-cxx20-note@-4 {{while substituting template arguments into constraint expression here}}
312 //   since-cxx20-note@#cwg2672-f-0 {{while checking constraint satisfaction for template 'f<int>' required here}}
313 //   since-cxx20-note@#cwg2672-f-0 {{in instantiation of function template specialization 'cwg2672::f<int>' requested here}}
314 void f(...);
315 
316 template <class T>
317 void bar(T) requires requires {
318    []() -> decltype(T::foo()) {};
319 };
320 void bar(...);
321 
322 void m() {
323   f(0); // #cwg2672-f-0
324   bar(0);
325 }
326 #endif
327 } // namespace cwg2672
328 
329 namespace cwg2687 { // cwg2687: 18
330 #if __cplusplus >= 202302L
331 struct S{
332     void f(int);
333     static void g(int);
334     void h(this const S&, int);
335 };
336 
337 void test() {
338     (&S::f)(1);
339     // since-cxx23-error@-1 {{called object type 'void (cwg2687::S::*)(int)' is not a function or function pointer}}
340     (&S::g)(1);
341     (&S::h)(S(), 1);
342 }
343 #endif
344 } // namespace cwg2687
345 
346 namespace cwg2692 { // cwg2692: 19
347 #if __cplusplus >= 202302L
348 
349  struct A {
350     static void f(A); // #cwg2692-1
351     void f(this A); // #cwg2692-2
352 
353     void g();
354   };
355 
356   void A::g() {
357     (&A::f)(A());
358     // since-cxx23-error@-1 {{call to 'f' is ambiguous}}
359     //   since-cxx23-note@#cwg2692-1 {{candidate function}}
360     //   since-cxx23-note@#cwg2692-2 {{candidate function}}
361     (&A::f)();
362     // since-cxx23-error@-1 {{no matching function for call to 'f'}}
363     //   since-cxx23-note@#cwg2692-1 {{candidate function not viable: requires 1 argument, but 0 were provided}}
364     //   since-cxx23-note@#cwg2692-2 {{candidate function not viable: requires 1 argument, but 0 were provided}}
365   }
366 #endif
367 } // namespace cwg2692
368