xref: /llvm-project/clang/test/CXX/drs/cwg24xx.cpp (revision eff126501efc3981727ef0e918c4dca0fa2eb778)
1 // RUN: %clang_cc1 -std=c++98 -pedantic-errors %s -verify=expected,cxx98-14
2 // RUN: %clang_cc1 -std=c++11 -pedantic-errors %s -verify=expected,cxx98-14
3 // RUN: %clang_cc1 -std=c++14 -pedantic-errors %s -verify=expected,cxx98-14
4 // RUN: %clang_cc1 -std=c++17 -pedantic-errors %s -verify=expected,since-cxx17
5 // RUN: %clang_cc1 -std=c++20 -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17
6 // RUN: %clang_cc1 -std=c++23 -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17
7 // RUN: %clang_cc1 -std=c++2c -pedantic-errors %s -verify=expected,since-cxx20,since-cxx17
8 
9 namespace cwg2406 { // cwg2406: 5
10 #if __cplusplus >= 201703L
11 void fallthrough(int n) {
12   void g(), h(), i();
13   switch (n) {
14   case 1:
15   case 2:
16     g();
17     [[fallthrough]];
18   case 3: // warning on fallthrough discouraged
19     do {
20       [[fallthrough]];
21       // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
22     } while (false);
23   case 6:
24     do {
25       [[fallthrough]];
26       // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
27     } while (n);
28   case 7:
29     while (false) {
30       [[fallthrough]];
31       // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
32     }
33   case 5:
34     h();
35   case 4: // implementation may warn on fallthrough
36     i();
37     [[fallthrough]];
38     // since-cxx17-error@-1 {{fallthrough annotation does not directly precede switch label}}
39   }
40 }
41 #endif
42 } // namespace cwg2406
43 
44 namespace cwg2428 { // cwg2428: 19
45 #if __cplusplus >= 202002L
46 template <typename>
47 concept C [[deprecated]] = true; // #cwg2428-C
48 
49 template <typename>
50 [[deprecated]] concept C2 = true;
51 // since-cxx20-error@-1 {{expected unqualified-id}}
52 
53 template <typename T>
54 concept C3 = C<T>;
55 // since-cxx20-warning@-1 {{'C' is deprecated}}
56 //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
57 
58 template <typename T, C U>
59 // since-cxx20-warning@-1 {{'C' is deprecated}}
60 //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
61 requires C<T>
62 // since-cxx20-warning@-1 {{'C' is deprecated}}
63 //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
64 void f() {
65   bool b = C<int>;
66   // since-cxx20-warning@-1 {{'C' is deprecated}}
67   //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
68 };
69 
70 void g(C auto a) {};
71 // since-cxx20-warning@-1 {{'C' is deprecated}}
72 //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
73 
74 template <typename T>
75 auto h() -> C auto {
76 // since-cxx20-warning@-1 {{'C' is deprecated}}
77 //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
78   C auto foo = T();
79   // since-cxx20-warning@-1 {{'C' is deprecated}}
80   //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
81   C auto *bar = T();
82   // since-cxx20-warning@-1 {{'C' is deprecated}}
83   //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
84   C auto &baz = T();
85   // since-cxx20-warning@-1 {{'C' is deprecated}}
86   //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
87   C auto &&quux = T();
88   // since-cxx20-warning@-1 {{'C' is deprecated}}
89   //   since-cxx20-note@#cwg2428-C {{'C' has been explicitly marked deprecated here}}
90   return foo;
91 }
92 #endif
93 } // namespace cwg2428
94 
95 namespace cwg2430 { // cwg2430: 2.7
96 struct S {
97   S f(S s) { return s; }
98 };
99 } // namespace cwg2430
100 
101 namespace cwg2450 { // cwg2450: 18
102 #if __cplusplus >= 202302L
103 struct S {int a;};
104 template <S s>
105 void f(){}
106 
107 void test() {
108 f<{0}>();
109 f<{.a= 0}>();
110 }
111 
112 #endif
113 } // namespace cwg2450
114 
115 namespace cwg2459 { // cwg2459: 18
116 #if __cplusplus >= 202302L
117 struct A {
118   constexpr A(float) {}
119 };
120 template<A> struct X {};
121 X<1> x;
122 #endif
123 } // namespace cwg2459
124 
125 namespace cwg2445 { // cwg2445: 19
126 #if __cplusplus >= 202002L
127   template <typename> constexpr bool F = false;
128   template <typename T> struct A { };
129 
130   template <typename T, typename U>
131   bool operator==(T, A<U *>);
132 
133   template <typename T, typename U>
134   bool operator!=(A<T>, U) {
135    static_assert(F<T>, "Isn't this less specialized?");
136    return false;
137   }
138 
139   bool f(A<int> ax, A<int *> ay) { return ay != ax; }
140 
141   template<class T> concept AlwaysTrue=true;
142   template <class T> struct B {
143     template <AlwaysTrue U>
144     bool operator==(const B<U>&)const;
145   };
146 
147 
148   template <typename U>
149   bool operator==(const B<int>&,const B<U>&) {
150    static_assert(F<int>, "Isn't this less specialized?");
151    return false;
152   }
153 
154   bool g(B<int> bx, B<int *> by) { return bx == by; }
155 
156   struct C{
157     template<AlwaysTrue T>
158     int operator+(T){return 0;}
159     template<class T>
160     void operator-(T){}
161   };
162   template<class T>
163   void operator+(C&&,T){}
164   template<AlwaysTrue T>
165   int operator-(C&&,T){return 0;}
166 
167   void t(int* iptr){
168     int x1 = C{} + iptr;
169     int x2 = C{} - iptr;
170   }
171 
172   struct D{
173     template<AlwaysTrue T>
174     int operator+(T) volatile {return 1;}
175   };
176 
177   template<class T>
178   void operator+(volatile D&,T) {}
179 
180   int foo(volatile D& d){
181     return d + 1;
182   }
183 #endif
184 } // namespace cwg2445
185 
186 namespace cwg2486 { // cwg2486: 4 c++17
187 struct C {
188   void fn() throw();
189 };
190 
191 static void call(C& c, void (C::*f)()) {
192   (c.*f)();
193 }
194 
195 static void callNE(C& c, void (C::*f)() throw()) {
196 // cxx98-14-warning@-1 {{mangled name of 'callNE' will change in C++17 due to non-throwing exception specification in function signature}}
197   (c.*f)();
198 }
199 
200 void ref() {
201   C c;
202   call(c, &C::fn); // <= implicit cast removes noexcept
203   callNE(c, &C::fn);
204 }
205 
206 void (*p)();
207 void (*pp)() throw() = p;
208 // since-cxx17-error@-1 {{cannot initialize a variable of type 'void (*)() throw()' with an lvalue of type 'void (*)()': different exception specifications}}
209 
210 struct S {
211   typedef void (*p)();
212   operator p(); // #cwg2486-conv
213 };
214 void (*q)() throw() = S();
215 // since-cxx17-error@-1 {{no viable conversion from 'S' to 'void (*)() throw()'}}
216 //   since-cxx17-note@#cwg2486-conv {{candidate function}}
217 } // namespace cwg2486
218