1 // RUN: %clang_cc1 -std=c++98 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 2 // RUN: %clang_cc1 -std=c++98 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -fms-compatibility 3 // RUN: %clang_cc1 -std=c++11 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 4 // RUN: %clang_cc1 -std=c++11 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -fms-compatibility 5 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 6 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -fms-compatibility 7 // RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 8 // RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -fms-compatibility 9 // RUN: %clang_cc1 -std=c++2a %s -Wno-parentheses -Wdeprecated -verify=expected,cxx20 -triple x86_64-linux-gnu 10 // RUN: %clang_cc1 -std=c++2a %s -Wno-parentheses -Wdeprecated -verify=expected,cxx20 -triple x86_64-linux-gnu -fms-compatibility 11 12 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS 13 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu -Wno-deprecated-register -DNO_DEPRECATED_FLAGS -fms-compatibility 14 15 #include "Inputs/register.h" 16 17 namespace std { 18 struct type_info {}; 19 } 20 21 void g() throw(); 22 void h() throw(int); 23 void i() throw(...); 24 #if __cplusplus > 201402L 25 // expected-warning@-4 {{dynamic exception specifications are deprecated}} expected-note@-4 {{use 'noexcept' instead}} 26 // expected-error@-4 {{ISO C++17 does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}} 27 // expected-error@-4 {{ISO C++17 does not allow dynamic exception specifications}} expected-note@-4 {{use 'noexcept(false)' instead}} 28 #elif __cplusplus >= 201103L 29 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept' instead}} 30 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}} 31 // expected-warning@-8 {{dynamic exception specifications are deprecated}} expected-note@-8 {{use 'noexcept(false)' instead}} 32 #endif 33 34 void stuff(register int q) { 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 register int n; 41 #if __cplusplus > 201402L 42 // expected-error@-2 {{ISO C++17 does not allow 'register' storage class specifier}} 43 #elif __cplusplus >= 201103L && !defined(NO_DEPRECATED_FLAGS) 44 // expected-warning@-4 {{'register' storage class specifier is deprecated}} 45 #endif 46 47 register int m asm("rbx"); // no-warning 48 49 int k = to_int(n); // no-warning 50 bool b; 51 ++b; 52 #if __cplusplus > 201402L 53 // expected-error@-2 {{ISO C++17 does not allow incrementing expression of type bool}} 54 #else 55 // expected-warning@-4 {{incrementing expression of type bool is deprecated}} 56 #endif 57 58 b++; 59 #if __cplusplus > 201402L 60 // expected-error@-2 {{ISO C++17 does not allow incrementing expression of type bool}} 61 #else 62 // expected-warning@-4 {{incrementing expression of type bool is deprecated}} 63 #endif 64 65 char *p = "foo"; 66 #if __cplusplus < 201103L 67 // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}} 68 #else 69 // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}} 70 #endif 71 } 72 73 struct S { int n; void operator+(int); }; 74 struct T : private S { 75 S::n; 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 S::operator+; 82 #if __cplusplus < 201103L 83 // expected-warning@-2 {{access declarations are deprecated; use using declarations instead}} 84 #else 85 // expected-error@-4 {{ISO C++11 does not allow access declarations; use using declarations instead}} 86 #endif 87 }; 88 89 #if __cplusplus >= 201103L 90 namespace DeprecatedCopy { 91 struct Assign { 92 Assign &operator=(const Assign&); // expected-warning {{definition of implicit copy constructor for 'Assign' is deprecated because it has a user-provided copy assignment operator}} 93 }; 94 Assign a1, a2(a1); // expected-note {{implicit copy constructor for 'DeprecatedCopy::Assign' first required here}} 95 96 struct Ctor { 97 Ctor(); 98 Ctor(const Ctor&); // expected-warning {{definition of implicit copy assignment operator for 'Ctor' is deprecated because it has a user-provided copy constructor}} 99 }; 100 Ctor b1, b2; 101 void f() { b1 = b2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Ctor' first required here}} 102 103 struct Dtor { 104 ~Dtor(); 105 // expected-warning@-1 {{definition of implicit copy constructor for 'Dtor' is deprecated because it has a user-provided destructor}} 106 // expected-warning@-2 {{definition of implicit copy assignment operator for 'Dtor' is deprecated because it has a user-provided destructor}} 107 }; 108 Dtor c1, c2(c1); // expected-note {{implicit copy constructor for 'DeprecatedCopy::Dtor' first required here}} 109 void g() { c1 = c2; } // expected-note {{implicit copy assignment operator for 'DeprecatedCopy::Dtor' first required here}} 110 111 struct DefaultedDtor { 112 ~DefaultedDtor() = default; // expected-warning {{definition of implicit copy constructor for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} 113 }; // expected-warning@-1 {{definition of implicit copy assignment operator for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} 114 DefaultedDtor d1; 115 DefaultedDtor d2(d1); // expected-note {{in implicit copy constructor for 'DeprecatedCopy::DefaultedDtor' first required here}} 116 void h() { d1 = d2; } // expected-note {{in implicit copy assignment operator for 'DeprecatedCopy::DefaultedDtor' first required here}} 117 } 118 #endif 119 120 struct X { 121 friend int operator,(X, X); 122 void operator[](int); 123 }; 124 void array_index_comma() { 125 int arr[123]; 126 (void)arr[(void)1, 2]; 127 (void)arr[X(), X()]; 128 X()[(void)1, 2]; 129 X()[X(), X()]; 130 #if __cplusplus > 201703L 131 // expected-warning@-5 {{deprecated}} 132 // expected-warning@-5 {{deprecated}} 133 // expected-warning@-5 {{deprecated}} 134 // expected-warning@-5 {{deprecated}} 135 #endif 136 137 (void)arr[((void)1, 2)]; 138 (void)arr[(X(), X())]; 139 (void)((void)1,2)[arr]; 140 (void)(X(), X())[arr]; 141 X()[((void)1, 2)]; 142 X()[(X(), X())]; 143 } 144 145 namespace DeprecatedVolatile { 146 volatile int n = 1; 147 void use(int); 148 void f() { 149 // simple assignments are deprecated only if their value is used 150 n = 5; // ok 151 #if __cplusplus >= 201103L 152 decltype(n = 5) m = n; // ok expected-warning {{side effects}} 153 (void)noexcept(n = 5); // ok expected-warning {{side effects}} 154 #endif 155 (void)typeid(n = 5); // ok expected-warning {{side effects}} 156 (n = 5, 0); // ok 157 use(n = 5); // cxx20-warning {{use of result of assignment to object of volatile-qualified type 'volatile int' is deprecated}} 158 int q = n = 5; // cxx20-warning {{deprecated}} 159 q = n = 5; // cxx20-warning {{deprecated}} 160 #if __cplusplus >= 201103L 161 decltype(q = n = 5) m2 = q; // cxx20-warning {{deprecated}} expected-warning {{side effects}} 162 (void)noexcept(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 163 #endif 164 (void)sizeof(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 165 (void)typeid(use(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 166 (void)__alignof(+(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 167 168 // FIXME: These cases are technically deprecated because the parens are 169 // part of the operand, but we choose to not diagnose for now. 170 (void)sizeof(n = 5); // expected-warning {{side effects}} 171 (void)__alignof(n = 5); // expected-warning {{side effects}} 172 // Similarly here. 173 (n = 5); 174 175 volatile bool b = true; 176 if (b = true) {} // cxx20-warning {{deprecated}} 177 for (b = true; 178 b = true; // cxx20-warning {{deprecated}} 179 b = true) {} 180 for (volatile bool x = true; 181 volatile bool y = true; // ok despite volatile load from volatile initialization 182 ) {} 183 184 // inc / dec / compound assignments are always deprecated 185 ++n; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}} 186 --n; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}} 187 n++; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}} 188 n--; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}} 189 n += 5; // undeprecated as a DR in C++23 190 n *= 3; // undeprecated as a DR in C++23 191 n /= 2; // undeprecated as a DR in C++23 192 n %= 42; // undeprecated as a DR in C++23 193 n &= 2; // undeprecated as a DR in C++23 194 n |= 2; // undeprecated as a DR in C++23 195 n ^= 2; // undeprecated as a DR in C++23 196 197 (void)__is_trivially_assignable(volatile int&, int); // no warning 198 199 #if __cplusplus >= 201703L 200 struct X { int a, b; }; 201 volatile auto [x, y] = X{1, 2}; // cxx20-warning {{volatile qualifier in structured binding declaration is deprecated}} 202 203 struct Y { volatile int a, b; }; 204 auto [x2, y2] = Y{1, 2}; // ok 205 #endif 206 } 207 volatile int g( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}} 208 volatile int n, // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}} 209 volatile int (*p)( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}} 210 volatile int m) // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}} 211 ); 212 #if __cplusplus >= 201103L 213 auto lambda = []( // cxx20-warning{{volatile-qualified return type 'volatile int' is deprecated}} 214 volatile int n) // cxx20-warning{{volatile-qualified parameter type 'volatile int' is deprecated}} 215 -> volatile int { return n; }; 216 #endif 217 218 template<typename T> T f(T v); // cxx20-warning 2{{deprecated}} 219 int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note. 220 221 // OK, only the built-in operators are deprecated. 222 struct UDT { 223 UDT(volatile const UDT&); 224 UDT &operator=(const UDT&); 225 UDT &operator=(const UDT&) volatile; 226 UDT operator+=(const UDT&) volatile; 227 }; 228 void h(UDT a) { 229 volatile UDT b = a; 230 volatile UDT c = b; 231 a = c = a; 232 b += a; 233 } 234 } 235 236 namespace ArithConv { 237 enum E { e } e2; 238 enum F { f }; 239 bool b1 = e == e2; 240 bool b2 = e == f; // not-cxx20-warning-re {{different enumeration types ('ArithConv::E' and 'ArithConv::F'){{$}}}} cxx20-warning {{F') is deprecated}} 241 bool b3 = e == 0.0; // cxx20-warning {{comparison of enumeration type 'ArithConv::E' with floating-point type 'double' is deprecated}} 242 bool b4 = 0.0 == f; // cxx20-warning {{comparison of floating-point type 'double' with enumeration type 'ArithConv::F' is deprecated}} 243 int n1 = true ? e : f; // cxx20-warning {{conditional expression between different enumeration types ('ArithConv::E' and 'ArithConv::F') is deprecated}} 244 int n2 = true ? e : 0.0; // cxx20-warning {{conditional expression between enumeration type 'ArithConv::E' and floating-point type 'double' is deprecated}} 245 } 246 247 namespace ArrayComp { 248 int arr1[3], arr2[4]; 249 bool b1 = arr1 == arr2; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} 250 // expected-warning@-1 {{array comparison always evaluates to false}} 251 bool b2 = arr1 < arr2; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} 252 // expected-warning@-1 {{array comparison always evaluates to a constant}} 253 __attribute__((weak)) int arr3[3]; 254 bool b3 = arr1 == arr3; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} 255 bool b4 = arr1 < arr3; // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} 256 #if __cplusplus > 201703L 257 bool b5 = arr1 <=> arr2; // cxx20-error {{invalid operands}} 258 #endif 259 260 int (&f())[3]; 261 bool b6 = arr1 == f(); // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} 262 bool b7 = arr1 == +f(); 263 } 264 265 namespace GH90073 { 266 [[deprecated]] int f1() { // expected-note {{'f1' has been explicitly marked deprecated here}} 267 [[deprecated]] int a; // expected-note {{'a' has been explicitly marked deprecated here}} \ 268 // expected-note {{'a' has been explicitly marked deprecated here}} 269 a = 0; // expected-warning {{'a' is deprecated}} 270 return a; // expected-warning {{'a' is deprecated}} 271 } 272 273 [[deprecated]] void f2([[deprecated]] int x) { // expected-note {{'f2' has been explicitly marked deprecated here}} \ 274 // expected-note {{'x' has been explicitly marked deprecated here}} 275 x = 4; // expected-warning {{'x' is deprecated}} 276 } 277 278 int main() { 279 f1(); // expected-warning {{'f1' is deprecated}} 280 f2(1); // expected-warning {{'f2' is deprecated}} 281 return 0; 282 } 283 } 284 285 # 1 "/usr/include/system-header.h" 1 3 286 void system_header_function(void) throw(); 287