1 // RUN: %clang_cc1 -std=c++98 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
2 // RUN: %clang_cc1 -std=c++11 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
3 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
4 // RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu
5 // RUN: %clang_cc1 -std=c++2a %s -Wno-parentheses -Wdeprecated -verify=expected,cxx20 -triple x86_64-linux-gnu
6 
7 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS
8 
9 #include "Inputs/register.h"
10 
11 namespace std {
12   struct type_info {};
13 }
14 
15 void g() throw();
16 void h() throw(int);
17 void i() throw(...);
18 #if __cplusplus > 201402L
19 // expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}}
20 // expected-error@-4 {{ISO C++17 does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}}
21 // expected-error@-4 {{ISO C++17 does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}}
22 #elif __cplusplus >= 201103L
23 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept' instead}}
24 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
25 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}}
26 #endif
27 
28 void stuff(register int q) {
29 #if __cplusplus > 201402L
30   // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
31 #elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS)
32   // expected-warning@-4 {{'register' storage class specifier is deprecated}}
33 #endif
34   register int n;
35 #if __cplusplus > 201402L
36   // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}}
37 #elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS)
38   // expected-warning@-4 {{'register' storage class specifier is deprecated}}
39 #endif
40 
41   register int m asm("rbx"); // no-warning
42 
43   int k = to_int(n); // no-warning
44   bool b;
45   ++b;
46 #if __cplusplus > 201402L
47   // expected-error@-2 {{ISO C++17 does not allow incrementing expression of type bool}}
48 #else
49   // expected-warning@-4 {{incrementing expression of type bool is deprecated}}
50 #endif
51 
52   b++;
53 #if __cplusplus > 201402L
54   // expected-error@-2 {{ISO C++17 does not allow incrementing expression of type bool}}
55 #else
56   // expected-warning@-4 {{incrementing expression of type bool is deprecated}}
57 #endif
58 
59   char *p = "foo";
60 #if __cplusplus < 201103L
61   // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
62 #else
63   // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
64 #endif
65 }
66 
67 struct S { int n; void operator+(int); };
68 struct T : private S {
69   S::n;
70 #if __cplusplus < 201103L
71   // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
72 #else
73   // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
74 #endif
75   S::operator+;
76 #if __cplusplus < 201103L
77   // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}}
78 #else
79   // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}}
80 #endif
81 };
82 
83 #if __cplusplus >= 201103L
84 namespace DeprecatedCopy {
85   struct Assign {
86     Assign &operator=(const Assign&); // expected-warning {{definition of implicit copy constructor for 'Assign' is deprecated because it has a user-declared copy assignment operator}}
87   };
88   Assign a1, a2(a1); // expected-note {{implicit copy constructor for 'DeprecatedCopy::Assign' first required here}}
89 
90   struct Ctor {
91     Ctor();
92     Ctor(const Ctor&); // expected-warning {{definition of implicit copy assignment operator for 'Ctor' is deprecated because it has a user-declared copy constructor}}
93   };
94   Ctor b1, b2;
95   void f() { b1 = b2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Ctor' first required here}}
96 
97   struct Dtor {
98     ~Dtor();
99     // expected-warning@-1 {{definition of implicit copy constructor for 'Dtor' is deprecated because it has a user-declared destructor}}
100     // expected-warning@-2 {{definition of implicit copy assignment operator for 'Dtor' is deprecated because it has a user-declared destructor}}
101   };
102   Dtor c1, c2(c1); // expected-note {{implicit copy constructor for 'DeprecatedCopy::Dtor' first required here}}
103   void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}}
104 }
105 #endif
106 
107 struct X {
108   friend int operator,(X, X);
109   void operator[](int);
110 };
111 void array_index_comma() {
112   int arr[123];
113   (void)arr[(void)1, 2];
114   (void)arr[X(), X()];
115   X()[(void)1, 2];
116   X()[X(), X()];
117 #if __cplusplus > 201703L
118   // expected-warning@-5 {{deprecated}}
119   // expected-warning@-5 {{deprecated}}
120   // expected-warning@-5 {{deprecated}}
121   // expected-warning@-5 {{deprecated}}
122 #endif
123 
124   (void)arr[((void)1, 2)];
125   (void)arr[(X(), X())];
126   (void)((void)1,2)[arr];
127   (void)(X(), X())[arr];
128   X()[((void)1, 2)];
129   X()[(X(), X())];
130 }
131 
132 namespace DeprecatedVolatile {
133   volatile int n = 1;
134   void use(int);
135   void f() {
136     // simple assignments are deprecated only if their value is used
137     n = 5; // ok
138 #if __cplusplus >= 201103L
139     decltype(n = 5) m = n; // ok expected-warning {{side effects}}
140     (void)noexcept(n = 5); // ok expected-warning {{side effects}}
141 #endif
142     (void)typeid(n = 5); // ok expected-warning {{side effects}}
143     (n = 5, 0); // ok
144     use(n = 5); // cxx20-warning {{use of result of assignment to object of volatile-qualified type 'volatile int' is deprecated}}
145     int q = n = 5; // cxx20-warning {{deprecated}}
146     q = n = 5; // cxx20-warning {{deprecated}}
147 #if __cplusplus >= 201103L
148     decltype(q = n = 5) m2 = q; // cxx20-warning {{deprecated}} expected-warning {{side effects}}
149     (void)noexcept(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}}
150 #endif
151     (void)sizeof(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}}
152     (void)typeid(use(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}}
153     (void)__alignof(+(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}}
154 
155     // FIXME: These cases are technically deprecated because the parens are
156     // part of the operand, but we choose to not diagnose for now.
157     (void)sizeof(n = 5); // expected-warning {{side effects}}
158     (void)__alignof(n = 5); // expected-warning {{side effects}}
159     // Similarly here.
160     (n = 5);
161 
162     volatile bool b = true;
163     if (b = true) {} // cxx20-warning {{deprecated}}
164     for (b = true;
165          b = true; // cxx20-warning {{deprecated}}
166          b = true) {}
167     for (volatile bool x = true;
168          volatile bool y = true; // ok despite volatile load from volatile initialization
169         ) {}
170 
171     // inc / dec / compound assignments are always deprecated
172     ++n; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}}
173     --n; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}}
174     n++; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}}
175     n--; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}}
176     n += 5; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
177     n *= 3; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
178     n /= 2; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
179     n %= 42; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}}
180 
181     (void)__is_trivially_assignable(volatile int&, int); // no warning
182 
183 #if __cplusplus >= 201703L
184     struct X { int a, b; };
185     volatile auto [x, y] = X{1, 2}; // cxx20-warning {{volatile qualifier in structured binding declaration is deprecated}}
186 
187     struct Y { volatile int a, b; };
188     auto [x2, y2] = Y{1, 2}; // ok
189 #endif
190   }
191   volatile int g( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}}
192       volatile int n, // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}}
193       volatile int (*p)( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}}
194         volatile int m) // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}}
195       );
196 #if __cplusplus >= 201103L
197   auto lambda = []( // cxx20-warning{{volatile-qualified return type 'volatile int' is deprecated}}
198       volatile int n) // cxx20-warning{{volatile-qualified parameter type 'volatile int' is deprecated}}
199     -> volatile int { return n; };
200 #endif
201 
202   template<typename T> T f(T v); // cxx20-warning 2{{deprecated}}
203   int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note.
204 
205   // OK, only the built-in operators are deprecated.
206   struct UDT {
207     UDT(volatile const UDT&);
208     UDT &operator=(const UDT&);
209     UDT &operator=(const UDT&) volatile;
210     UDT operator+=(const UDT&) volatile;
211   };
212   void h(UDT a) {
213     volatile UDT b = a;
214     volatile UDT c = b;
215     a = c = a;
216     b += a;
217   }
218 }
219 
220 # 1 "/usr/include/system-header.h" 1 3
221 void system_header_function(void) throw();
222