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++11 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 3 // RUN: %clang_cc1 -std=c++14 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -triple x86_64-linux-gnu 4 // RUN: %clang_cc1 -std=c++17 %s -Wno-parentheses -Wdeprecated -verify=expected,not-cxx20 -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=expected,not-cxx20 -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-provided 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-provided 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-provided destructor}} 100 // expected-warning@-2 {{definition of implicit copy assignment operator for 'Dtor' is deprecated because it has a user-provided 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 struct DefaultedDtor { 106 ~DefaultedDtor() = default; // expected-warning {{definition of implicit copy constructor for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} 107 }; // expected-warning@-1 {{definition of implicit copy assignment operator for 'DefaultedDtor' is deprecated because it has a user-declared destructor}} 108 DefaultedDtor d1; 109 DefaultedDtor d2(d1); // expected-note {{in implicit copy constructor for 'DeprecatedCopy::DefaultedDtor' first required here}} 110 void h() { d1 = d2; } // expected-note {{in implicit copy assignment operator for 'DeprecatedCopy::DefaultedDtor' first required here}} 111 } 112 #endif 113 114 struct X { 115 friend int operator,(X, X); 116 void operator[](int); 117 }; 118 void array_index_comma() { 119 int arr[123]; 120 (void)arr[(void)1, 2]; 121 (void)arr[X(), X()]; 122 X()[(void)1, 2]; 123 X()[X(), X()]; 124 #if __cplusplus > 201703L 125 // expected-warning@-5 {{deprecated}} 126 // expected-warning@-5 {{deprecated}} 127 // expected-warning@-5 {{deprecated}} 128 // expected-warning@-5 {{deprecated}} 129 #endif 130 131 (void)arr[((void)1, 2)]; 132 (void)arr[(X(), X())]; 133 (void)((void)1,2)[arr]; 134 (void)(X(), X())[arr]; 135 X()[((void)1, 2)]; 136 X()[(X(), X())]; 137 } 138 139 namespace DeprecatedVolatile { 140 volatile int n = 1; 141 void use(int); 142 void f() { 143 // simple assignments are deprecated only if their value is used 144 n = 5; // ok 145 #if __cplusplus >= 201103L 146 decltype(n = 5) m = n; // ok expected-warning {{side effects}} 147 (void)noexcept(n = 5); // ok expected-warning {{side effects}} 148 #endif 149 (void)typeid(n = 5); // ok expected-warning {{side effects}} 150 (n = 5, 0); // ok 151 use(n = 5); // cxx20-warning {{use of result of assignment to object of volatile-qualified type 'volatile int' is deprecated}} 152 int q = n = 5; // cxx20-warning {{deprecated}} 153 q = n = 5; // cxx20-warning {{deprecated}} 154 #if __cplusplus >= 201103L 155 decltype(q = n = 5) m2 = q; // cxx20-warning {{deprecated}} expected-warning {{side effects}} 156 (void)noexcept(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 157 #endif 158 (void)sizeof(q = n = 5); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 159 (void)typeid(use(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 160 (void)__alignof(+(n = 5)); // cxx20-warning {{deprecated}} expected-warning {{side effects}} 161 162 // FIXME: These cases are technically deprecated because the parens are 163 // part of the operand, but we choose to not diagnose for now. 164 (void)sizeof(n = 5); // expected-warning {{side effects}} 165 (void)__alignof(n = 5); // expected-warning {{side effects}} 166 // Similarly here. 167 (n = 5); 168 169 volatile bool b = true; 170 if (b = true) {} // cxx20-warning {{deprecated}} 171 for (b = true; 172 b = true; // cxx20-warning {{deprecated}} 173 b = true) {} 174 for (volatile bool x = true; 175 volatile bool y = true; // ok despite volatile load from volatile initialization 176 ) {} 177 178 // inc / dec / compound assignments are always deprecated 179 ++n; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}} 180 --n; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}} 181 n++; // cxx20-warning {{increment of object of volatile-qualified type 'volatile int' is deprecated}} 182 n--; // cxx20-warning {{decrement of object of volatile-qualified type 'volatile int' is deprecated}} 183 n += 5; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}} 184 n *= 3; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}} 185 n /= 2; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}} 186 n %= 42; // cxx20-warning {{compound assignment to object of volatile-qualified type 'volatile int' is deprecated}} 187 188 (void)__is_trivially_assignable(volatile int&, int); // no warning 189 190 #if __cplusplus >= 201703L 191 struct X { int a, b; }; 192 volatile auto [x, y] = X{1, 2}; // cxx20-warning {{volatile qualifier in structured binding declaration is deprecated}} 193 194 struct Y { volatile int a, b; }; 195 auto [x2, y2] = Y{1, 2}; // ok 196 #endif 197 } 198 volatile int g( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}} 199 volatile int n, // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}} 200 volatile int (*p)( // cxx20-warning {{volatile-qualified return type 'volatile int' is deprecated}} 201 volatile int m) // cxx20-warning {{volatile-qualified parameter type 'volatile int' is deprecated}} 202 ); 203 #if __cplusplus >= 201103L 204 auto lambda = []( // cxx20-warning{{volatile-qualified return type 'volatile int' is deprecated}} 205 volatile int n) // cxx20-warning{{volatile-qualified parameter type 'volatile int' is deprecated}} 206 -> volatile int { return n; }; 207 #endif 208 209 template<typename T> T f(T v); // cxx20-warning 2{{deprecated}} 210 int use_f = f<volatile int>(0); // FIXME: Missing "in instantiation of" note. 211 212 // OK, only the built-in operators are deprecated. 213 struct UDT { 214 UDT(volatile const UDT&); 215 UDT &operator=(const UDT&); 216 UDT &operator=(const UDT&) volatile; 217 UDT operator+=(const UDT&) volatile; 218 }; 219 void h(UDT a) { 220 volatile UDT b = a; 221 volatile UDT c = b; 222 a = c = a; 223 b += a; 224 } 225 } 226 227 namespace ArithConv { 228 enum E { e } e2; 229 enum F { f }; 230 bool b1 = e == e2; 231 bool b2 = e == f; // not-cxx20-warning-re {{different enumeration types ('ArithConv::E' and 'ArithConv::F'){{$}}}} cxx20-warning {{F') is deprecated}} 232 bool b3 = e == 0.0; // cxx20-warning {{comparison of enumeration type 'ArithConv::E' with floating-point type 'double' is deprecated}} 233 bool b4 = 0.0 == f; // cxx20-warning {{comparison of floating-point type 'double' with enumeration type 'ArithConv::F' is deprecated}} 234 int n1 = true ? e : f; // cxx20-warning {{conditional expression between different enumeration types ('ArithConv::E' and 'ArithConv::F') is deprecated}} 235 int n2 = true ? e : 0.0; // cxx20-warning {{conditional expression between enumeration type 'ArithConv::E' and floating-point type 'double' is deprecated}} 236 } 237 238 namespace ArrayComp { 239 int arr1[3], arr2[4]; 240 bool b1 = arr1 == arr2; // expected-warning {{array comparison always evaluates to false}} cxx20-warning {{comparison between two arrays is deprecated}} 241 bool b2 = arr1 < arr2; // expected-warning {{array comparison always evaluates to a constant}} cxx20-warning {{comparison between two arrays is deprecated}} 242 __attribute__((weak)) int arr3[3]; 243 bool b3 = arr1 == arr3; // cxx20-warning {{comparison between two arrays is deprecated}} 244 bool b4 = arr1 < arr3; // cxx20-warning {{comparison between two arrays is deprecated}} 245 #if __cplusplus > 201703L 246 bool b5 = arr1 <=> arr2; // cxx20-error {{invalid operands}} 247 #endif 248 249 int (&f())[3]; 250 bool b6 = arr1 == f(); // cxx20-warning {{comparison between two arrays is deprecated}} 251 bool b7 = arr1 == +f(); 252 } 253 254 # 1 "/usr/include/system-header.h" 1 3 255 void system_header_function(void) throw(); 256