1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s 2// RUN: %clang_cc1 -fsyntax-only -std=c++14 -Wc++98-compat -verify %s -DCXX14COMPAT 3 4namespace std { 5 struct type_info; 6 using size_t = decltype(sizeof(0)); // expected-warning {{decltype}} expected-warning {{alias}} 7 template<typename T> struct initializer_list { 8 initializer_list(T*, size_t); 9 T *p; 10 size_t n; 11 T *begin(); 12 T *end(); 13 }; 14} 15 16template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}} 17class Variadic1 {}; 18 19template<template<typename> class ...T> // expected-warning {{variadic templates are incompatible with C++98}} 20class Variadic2 {}; 21 22template<int ...I> // expected-warning {{variadic templates are incompatible with C++98}} 23class Variadic3 {}; 24 25alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}} 26int with_attribute [[ ]]; // expected-warning {{C++11 attribute syntax is incompatible with C++98}} 27 28void Literals() { 29 (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}} 30 (void)u"str"; // expected-warning {{unicode literals are incompatible with C++98}} 31 (void)U"str"; // expected-warning {{unicode literals are incompatible with C++98}} 32 (void)u'x'; // expected-warning {{unicode literals are incompatible with C++98}} 33 (void)U'x'; // expected-warning {{unicode literals are incompatible with C++98}} 34 35 (void)u8R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 36 (void)uR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 37 (void)UR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 38 (void)R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 39 (void)LR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 40} 41 42template<typename T> struct S {}; 43namespace TemplateParsing { 44 S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}} 45 S< ::S<void>> t; // expected-warning {{consecutive right angle brackets are incompatible with C++98 (use '> >')}} 46} 47 48void Lambda() { 49 []{}(); // expected-warning {{lambda expressions are incompatible with C++98}} 50} 51 52struct Ctor { 53 Ctor(int, char); 54 Ctor(double, long); 55}; 56struct InitListCtor { 57 InitListCtor(std::initializer_list<bool>); 58}; 59 60int InitList(int i = {}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 61 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 62 (void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 63 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 64 (void)int{}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 65 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 66 int x { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} 67 S<int> s = {}; // ok, aggregate 68 s = {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} 69 std::initializer_list<int> xs = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} 70 auto ys = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} \ 71 // expected-warning {{'auto' type specifier is incompatible with C++98}} 72 Ctor c1 = { 1, 2 }; // expected-warning {{constructor call from initializer list is incompatible with C++98}} 73 Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}} 74 InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} 75 const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} 76 struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} 77 return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} 78} 79struct DelayedDefaultArgumentParseInitList { 80 void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} expected-warning {{scalar}} 81 } 82}; 83 84int operator"" _hello(const char *); // expected-warning {{literal operators are incompatible with C++98}} 85 86enum EnumFixed : int { // expected-warning {{enumeration types with a fixed underlying type are incompatible with C++98}} 87}; 88 89enum class EnumScoped { // expected-warning {{scoped enumerations are incompatible with C++98}} 90}; 91 92void Deleted() = delete; // expected-warning {{deleted function definitions are incompatible with C++98}} 93struct Defaulted { 94 Defaulted() = default; // expected-warning {{defaulted function definitions are incompatible with C++98}} 95}; 96 97int &&RvalueReference = 0; // expected-warning {{rvalue references are incompatible with C++98}} 98struct RefQualifier { 99 void f() &; // expected-warning {{reference qualifiers on functions are incompatible with C++98}} 100}; 101 102auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}} 103#ifdef CXX14COMPAT 104auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}} 105#endif 106 107void RangeFor() { 108 int xs[] = {1, 2, 3}; 109 for (int &a : xs) { // expected-warning {{range-based for loop is incompatible with C++98}} 110 } 111 for (auto &b : {1, 2, 3}) { 112 // expected-warning@-1 {{range-based for loop is incompatible with C++98}} 113 // expected-warning@-2 {{'auto' type specifier is incompatible with C++98}} 114 // expected-warning@-3 {{initialization of initializer_list object is incompatible with C++98}} 115 // expected-warning@-4 {{reference initialized from initializer list is incompatible with C++98}} 116 } 117 struct Agg { int a, b; } const &agg = { 1, 2 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} 118} 119 120struct InClassInit { 121 int n = 0; // expected-warning {{in-class initialization of non-static data members is incompatible with C++98}} 122}; 123 124struct OverrideControlBase { 125 virtual void f(); 126 virtual void g(); 127}; 128struct OverrideControl final : OverrideControlBase { // expected-warning {{'final' keyword is incompatible with C++98}} 129 virtual void f() override; // expected-warning {{'override' keyword is incompatible with C++98}} 130 virtual void g() final; // expected-warning {{'final' keyword is incompatible with C++98}} 131}; 132 133using AliasDecl = int; // expected-warning {{alias declarations are incompatible with C++98}} 134template<typename T> using AliasTemplate = T; // expected-warning {{alias declarations are incompatible with C++98}} 135 136inline namespace InlineNS { // expected-warning {{inline namespaces are incompatible with C++98}} 137} 138 139auto auto_deduction = 0; // expected-warning {{'auto' type specifier is incompatible with C++98}} 140int *p = new auto(0); // expected-warning {{'auto' type specifier is incompatible with C++98}} 141 142const int align_of = alignof(int); // expected-warning {{alignof expressions are incompatible with C++98}} 143char16_t c16 = 0; // expected-warning {{'char16_t' type specifier is incompatible with C++98}} 144char32_t c32 = 0; // expected-warning {{'char32_t' type specifier is incompatible with C++98}} 145constexpr int const_expr = 0; // expected-warning {{'constexpr' specifier is incompatible with C++98}} 146decltype(const_expr) decl_type = 0; // expected-warning {{'decltype' type specifier is incompatible with C++98}} 147__decltype(const_expr) decl_type2 = 0; // ok 148void no_except() noexcept; // expected-warning {{noexcept specifications are incompatible with C++98}} 149bool no_except_expr = noexcept(1 + 1); // expected-warning {{noexcept expressions are incompatible with C++98}} 150void *null = nullptr; // expected-warning {{'nullptr' is incompatible with C++98}} 151static_assert(true, "!"); // expected-warning {{static_assert declarations are incompatible with C++98}} 152 153struct InhCtorBase { 154 InhCtorBase(int); 155}; 156struct InhCtorDerived : InhCtorBase { 157 using InhCtorBase::InhCtorBase; // expected-warning {{inheriting constructors are incompatible with C++98}} 158}; 159 160struct FriendMember { 161 static void MemberFn(); 162 friend void FriendMember::MemberFn(); // expected-warning {{friend declaration naming a member of the declaring class is incompatible with C++98}} 163}; 164 165struct DelegCtor { 166 DelegCtor(int) : DelegCtor() {} // expected-warning {{delegating constructors are incompatible with C++98}} 167 DelegCtor(); 168}; 169 170template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}} 171 172template<typename T> int TemplateFn(T) { return 0; } 173void LocalTemplateArg() { 174 struct S {}; 175 TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}} 176} 177struct {} obj_of_unnamed_type; // expected-note {{here}} 178int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{unnamed type as template argument is incompatible with C++98}} 179 180namespace RedundantParensInAddressTemplateParam { 181 int n; 182 template<int*p> struct S {}; 183 S<(&n)> s; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}} 184 S<(((&n)))> t; // expected-warning {{redundant parentheses surrounding address non-type template argument are incompatible with C++98}} 185} 186 187namespace TemplateSpecOutOfScopeNs { 188 template<typename T> struct S {}; // expected-note {{here}} 189} 190template<> struct TemplateSpecOutOfScopeNs::S<char> {}; // expected-warning {{class template specialization of 'S' outside namespace 'TemplateSpecOutOfScopeNs' is incompatible with C++98}} 191 192struct Typename { 193 template<typename T> struct Inner {}; 194}; 195typename ::Typename TypenameOutsideTemplate(); // expected-warning {{use of 'typename' outside of a template is incompatible with C++98}} 196Typename::template Inner<int> TemplateOutsideTemplate(); // expected-warning {{use of 'template' keyword outside of a template is incompatible with C++98}} 197 198struct TrivialButNonPOD { 199 int f(int); 200private: 201 int k; 202}; 203void Ellipsis(int n, ...); 204void TrivialButNonPODThroughEllipsis() { 205 Ellipsis(1, TrivialButNonPOD()); // expected-warning {{passing object of trivial but non-POD type 'TrivialButNonPOD' through variadic function is incompatible with C++98}} 206} 207 208struct HasExplicitConversion { 209 explicit operator bool(); // expected-warning {{explicit conversion functions are incompatible with C++98}} 210}; 211 212struct Struct {}; 213enum Enum { enum_val = 0 }; 214struct BadFriends { 215 friend enum ::Enum; // expected-warning {{befriending enumeration type 'enum ::Enum' is incompatible with C++98}} 216 friend int; // expected-warning {{non-class friend type 'int' is incompatible with C++98}} 217 friend Struct; // expected-warning {{befriending 'Struct' without 'struct' keyword is incompatible with C++98}} 218}; 219 220int n = {}; // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 221 222class PrivateMember { 223 struct ImPrivate {}; 224}; 225template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}} 226 return typename T::ImPrivate(); 227} 228int SFINAEAccessControl(...) { return 0; } 229int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}} 230 231namespace UnionOrAnonStructMembers { 232 struct NonTrivCtor { 233 NonTrivCtor(); // expected-note 2{{user-provided default constructor}} 234 }; 235 struct NonTrivCopy { 236 NonTrivCopy(const NonTrivCopy&); // expected-note 2{{user-provided copy constructor}} 237 }; 238 struct NonTrivDtor { 239 ~NonTrivDtor(); // expected-note 2{{user-provided destructor}} 240 }; 241 union BadUnion { 242 NonTrivCtor ntc; // expected-warning {{union member 'ntc' with a non-trivial constructor is incompatible with C++98}} 243 NonTrivCopy ntcp; // expected-warning {{union member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}} 244 NonTrivDtor ntd; // expected-warning {{union member 'ntd' with a non-trivial destructor is incompatible with C++98}} 245 }; 246 struct Wrap { 247 struct { 248 NonTrivCtor ntc; // expected-warning {{anonymous struct member 'ntc' with a non-trivial constructor is incompatible with C++98}} 249 NonTrivCopy ntcp; // expected-warning {{anonymous struct member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}} 250 NonTrivDtor ntd; // expected-warning {{anonymous struct member 'ntd' with a non-trivial destructor is incompatible with C++98}} 251 }; 252 }; 253 union WithStaticDataMember { 254 static constexpr double d = 0.0; // expected-warning {{static data member 'd' in union is incompatible with C++98}} expected-warning {{'constexpr' specifier is incompatible with C++98}} 255 static const int n = 0; // expected-warning {{static data member 'n' in union is incompatible with C++98}} 256 static int k; // expected-warning {{static data member 'k' in union is incompatible with C++98}} 257 }; 258} 259 260int EnumNNS = Enum::enum_val; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}} 261template<typename T> void EnumNNSFn() { 262 int k = T::enum_val; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}} 263}; 264template void EnumNNSFn<Enum>(); // expected-note {{in instantiation}} 265 266void JumpDiagnostics(int n) { 267 goto DirectJump; // expected-warning {{jump from this goto statement to its label is incompatible with C++98}} 268 TrivialButNonPOD tnp1; // expected-note {{jump bypasses initialization of non-POD variable}} 269 270DirectJump: 271 void *Table[] = {&&DirectJump, &&Later}; 272 goto *Table[n]; // expected-warning {{jump from this indirect goto statement to one of its possible targets is incompatible with C++98}} 273 274 TrivialButNonPOD tnp2; // expected-note {{jump bypasses initialization of non-POD variable}} 275Later: // expected-note {{possible target of indirect goto statement}} 276 switch (n) { 277 TrivialButNonPOD tnp3; // expected-note {{jump bypasses initialization of non-POD variable}} 278 default: // expected-warning {{jump from switch statement to this case label is incompatible with C++98}} 279 return; 280 } 281} 282 283namespace UnevaluatedMemberAccess { 284 struct S { 285 int n; 286 int f() { return sizeof(S::n); } // ok 287 }; 288 int k = sizeof(S::n); // expected-warning {{use of non-static data member 'n' in an unevaluated context is incompatible with C++98}} 289 const std::type_info &ti = typeid(S::n); // expected-warning {{use of non-static data member 'n' in an unevaluated context is incompatible with C++98}} 290} 291 292namespace LiteralUCNs { 293 char c1 = '\u001e'; // expected-warning {{universal character name referring to a control character is incompatible with C++98}} 294 wchar_t c2 = L'\u0041'; // expected-warning {{specifying character 'A' with a universal character name is incompatible with C++98}} 295 const char *s1 = "foo\u0031"; // expected-warning {{specifying character '1' with a universal character name is incompatible with C++98}} 296 const wchar_t *s2 = L"bar\u0085"; // expected-warning {{universal character name referring to a control character is incompatible with C++98}} 297} 298 299namespace NonTypeTemplateArgs { 300 template<typename T, T v> struct S {}; 301 const int k = 5; // expected-note {{here}} 302 static void f() {} // expected-note {{here}} 303 S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}} 304 S<void(&)(), f> s2; // expected-warning {{non-type template argument referring to function 'f' with internal linkage is incompatible with C++98}} 305} 306 307namespace NullPointerTemplateArg { 308 struct A {}; 309 template<int*> struct X {}; 310 template<int A::*> struct Y {}; 311 X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} 312 Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} 313} 314 315namespace PR13480 { 316 struct basic_iterator { 317 basic_iterator(const basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-provided copy constructor}} 318 basic_iterator(basic_iterator &it) {} 319 }; 320 321 union test { 322 basic_iterator it; // expected-warning {{union member 'it' with a non-trivial copy constructor is incompatible with C++98}} 323 }; 324} 325 326namespace AssignOpUnion { 327 struct a { 328 void operator=(const a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-provided copy assignment operator}} 329 void operator=(a &it) {} 330 }; 331 332 struct b { 333 void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}} 334 }; 335 336 union test1 { 337 a x; // expected-warning {{union member 'x' with a non-trivial copy assignment operator is incompatible with C++98}} 338 b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}} 339 }; 340} 341 342namespace rdar11736429 { 343 struct X { // expected-note {{because type 'rdar11736429::X' has no default constructor}} 344 X(const X&) = delete; // expected-warning{{deleted function definitions are incompatible with C++98}} \ 345 // expected-note {{implicit default constructor suppressed by user-declared constructor}} 346 }; 347 348 union S { 349 X x; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}} 350 }; 351} 352 353template<typename T> T var = T(10); 354#ifdef CXX14COMPAT 355// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}} 356#else 357// expected-warning@-4 {{variable templates are a C++14 extension}} 358#endif 359 360// No diagnostic for specializations of variable templates; we will have 361// diagnosed the primary template. 362template<typename T> T* var<T*> = new T(); 363template<> int var<int> = 10; 364template int var<int>; 365float fvar = var<float>; 366 367class A { 368 template<typename T> static T var = T(10); 369#ifdef CXX14COMPAT 370// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}} 371#else 372// expected-warning@-4 {{variable templates are a C++14 extension}} 373#endif 374 375 template<typename T> static T* var<T*> = new T(); 376}; 377 378struct B { template<typename T> static T v; }; 379#ifdef CXX14COMPAT 380// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}} 381#else 382// expected-warning@-4 {{variable templates are a C++14 extension}} 383#endif 384 385template<typename T> T B::v = T(); 386#ifdef CXX14COMPAT 387// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++14}} 388#else 389// expected-warning@-4 {{variable templates are a C++14 extension}} 390#endif 391 392template<typename T> T* B::v<T*> = new T(); 393template<> int B::v<int> = 10; 394template int B::v<int>; 395float fsvar = B::v<float>; 396 397#ifdef CXX14COMPAT 398int digit_seps = 123'456; // expected-warning {{digit separators are incompatible with C++ standards before C++14}} 399#endif 400