1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s 2// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s 3// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-c++11-compat -verify %s -DCXX1YCOMPAT 4 5#ifndef CXX1YCOMPAT 6 7namespace std { 8 struct type_info; 9 using size_t = decltype(sizeof(0)); // expected-warning {{decltype}} expected-warning {{alias}} 10 template<typename T> struct initializer_list { 11 initializer_list(T*, size_t); 12 T *p; 13 size_t n; 14 T *begin(); 15 T *end(); 16 }; 17} 18 19template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}} 20class Variadic1 {}; 21 22template<template<typename> class ...T> // expected-warning {{variadic templates are incompatible with C++98}} 23class Variadic2 {}; 24 25template<int ...I> // expected-warning {{variadic templates are incompatible with C++98}} 26class Variadic3 {}; 27 28alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}} 29int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}} 30 31void Literals() { 32 (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}} 33 (void)u"str"; // expected-warning {{unicode literals are incompatible with C++98}} 34 (void)U"str"; // expected-warning {{unicode literals are incompatible with C++98}} 35 (void)u'x'; // expected-warning {{unicode literals are incompatible with C++98}} 36 (void)U'x'; // expected-warning {{unicode literals are incompatible with C++98}} 37 38 (void)u8R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 39 (void)uR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 40 (void)UR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 41 (void)R"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 42 (void)LR"X(str)X"; // expected-warning {{raw string literals are incompatible with C++98}} 43} 44 45template<typename T> struct S {}; 46namespace TemplateParsing { 47 S<::S<void> > s; // expected-warning {{'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98}} 48 S< ::S<void>> t; // expected-warning {{consecutive right angle brackets are incompatible with C++98 (use '> >')}} 49} 50 51void Lambda() { 52 []{}(); // expected-warning {{lambda expressions are incompatible with C++98}} 53} 54 55struct Ctor { 56 Ctor(int, char); 57 Ctor(double, long); 58}; 59struct InitListCtor { 60 InitListCtor(std::initializer_list<bool>); 61}; 62 63int InitList(int i = {}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 64 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 65 (void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 66 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 67 (void)int{}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \ 68 // expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}} 69 int x { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} 70 S<int> s = {}; // ok, aggregate 71 s = {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} 72 std::initializer_list<int> xs = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} 73 auto ys = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} \ 74 // expected-warning {{'auto' type specifier is incompatible with C++98}} 75 Ctor c1 = { 1, 2 }; // expected-warning {{constructor call from initializer list is incompatible with C++98}} 76 Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}} 77 InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} 78 const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} 79 struct { int a; const int &r; } rr = { 0, {0} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}} 80 return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}} 81} 82struct DelayedDefaultArgumentParseInitList { 83 void f(int i = {1}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} 84 } 85}; 86 87int operator"" _hello(const char *); // expected-warning {{literal operators are incompatible with C++98}} 88 89enum EnumFixed : int { // expected-warning {{enumeration types with a fixed underlying type are incompatible with C++98}} 90}; 91 92enum class EnumScoped { // expected-warning {{scoped enumerations are incompatible with C++98}} 93}; 94 95void Deleted() = delete; // expected-warning {{deleted function definitions are incompatible with C++98}} 96struct Defaulted { 97 Defaulted() = default; // expected-warning {{defaulted function definitions are incompatible with C++98}} 98}; 99 100int &&RvalueReference = 0; // expected-warning {{rvalue references are incompatible with C++98}} 101struct RefQualifier { 102 void f() &; // expected-warning {{reference qualifiers on functions are incompatible with C++98}} 103}; 104 105auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}} 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}} expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}} 226 return typename T::ImPrivate(); 227} 228int SFINAEAccessControl(...) { return 0; } 229int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); 230 231template<typename T> 232struct FriendRedefinition { 233 friend void Friend() {} // expected-warning {{friend function 'Friend' would be implicitly redefined in C++98}} expected-note {{previous}} 234}; 235FriendRedefinition<int> FriendRedef1; 236FriendRedefinition<char> FriendRedef2; // expected-note {{requested here}} 237 238namespace CopyCtorIssues { 239 struct Private { 240 Private(); 241 private: 242 Private(const Private&); // expected-note {{declared private here}} 243 }; 244 struct NoViable { 245 NoViable(); 246 NoViable(NoViable&); // expected-note {{not viable}} 247 }; 248 struct Ambiguous { 249 Ambiguous(); 250 Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}} 251 Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}} 252 }; 253 struct Deleted { 254 Private p; // expected-note {{implicitly deleted}} 255 }; 256 257 const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}} 258 const NoViable &b = NoViable(); // expected-warning {{copying variable of type 'CopyCtorIssues::NoViable' when binding a reference to a temporary would find no viable constructor in C++98}} 259 const Ambiguous &c = Ambiguous(); // expected-warning {{copying variable of type 'CopyCtorIssues::Ambiguous' when binding a reference to a temporary would find ambiguous constructors in C++98}} 260 const Deleted &d = Deleted(); // expected-warning {{copying variable of type 'CopyCtorIssues::Deleted' when binding a reference to a temporary would invoke a deleted constructor in C++98}} 261} 262 263namespace UnionOrAnonStructMembers { 264 struct NonTrivCtor { 265 NonTrivCtor(); // expected-note 2{{user-provided default constructor}} 266 }; 267 struct NonTrivCopy { 268 NonTrivCopy(const NonTrivCopy&); // expected-note 2{{user-provided copy constructor}} 269 }; 270 struct NonTrivDtor { 271 ~NonTrivDtor(); // expected-note 2{{user-provided destructor}} 272 }; 273 union BadUnion { 274 NonTrivCtor ntc; // expected-warning {{union member 'ntc' with a non-trivial constructor is incompatible with C++98}} 275 NonTrivCopy ntcp; // expected-warning {{union member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}} 276 NonTrivDtor ntd; // expected-warning {{union member 'ntd' with a non-trivial destructor is incompatible with C++98}} 277 }; 278 struct Wrap { 279 struct { 280 NonTrivCtor ntc; // expected-warning {{anonymous struct member 'ntc' with a non-trivial constructor is incompatible with C++98}} 281 NonTrivCopy ntcp; // expected-warning {{anonymous struct member 'ntcp' with a non-trivial copy constructor is incompatible with C++98}} 282 NonTrivDtor ntd; // expected-warning {{anonymous struct member 'ntd' with a non-trivial destructor is incompatible with C++98}} 283 }; 284 }; 285 union WithStaticDataMember { 286 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}} 287 static const int n = 0; // expected-warning {{static data member 'n' in union is incompatible with C++98}} 288 static int k; // expected-warning {{static data member 'k' in union is incompatible with C++98}} 289 }; 290} 291 292int EnumNNS = Enum::enum_val; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}} 293template<typename T> void EnumNNSFn() { 294 int k = T::enum_val; // expected-warning {{enumeration type in nested name specifier is incompatible with C++98}} 295}; 296template void EnumNNSFn<Enum>(); // expected-note {{in instantiation}} 297 298void JumpDiagnostics(int n) { 299 goto DirectJump; // expected-warning {{goto would jump into protected scope in C++98}} 300 TrivialButNonPOD tnp1; // expected-note {{jump bypasses initialization of non-POD variable}} 301 302DirectJump: 303 void *Table[] = {&&DirectJump, &&Later}; 304 goto *Table[n]; // expected-warning {{indirect goto might cross protected scopes in C++98}} 305 306 TrivialButNonPOD tnp2; // expected-note {{jump bypasses initialization of non-POD variable}} 307Later: // expected-note {{possible target of indirect goto}} 308 switch (n) { 309 TrivialButNonPOD tnp3; // expected-note {{jump bypasses initialization of non-POD variable}} 310 default: // expected-warning {{switch case would be in a protected scope in C++98}} 311 return; 312 } 313} 314 315namespace UnevaluatedMemberAccess { 316 struct S { 317 int n; 318 int f() { return sizeof(S::n); } // ok 319 }; 320 int k = sizeof(S::n); // expected-warning {{use of non-static data member 'n' in an unevaluated context is incompatible with C++98}} 321 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}} 322} 323 324namespace LiteralUCNs { 325 char c1 = '\u001e'; // expected-warning {{universal character name referring to a control character is incompatible with C++98}} 326 wchar_t c2 = L'\u0041'; // expected-warning {{specifying character 'A' with a universal character name is incompatible with C++98}} 327 const char *s1 = "foo\u0031"; // expected-warning {{specifying character '1' with a universal character name is incompatible with C++98}} 328 const wchar_t *s2 = L"bar\u0085"; // expected-warning {{universal character name referring to a control character is incompatible with C++98}} 329} 330 331namespace NonTypeTemplateArgs { 332 template<typename T, T v> struct S {}; 333 const int k = 5; // expected-note {{here}} 334 static void f() {} // expected-note {{here}} 335 S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}} 336 S<void(&)(), f> s2; // expected-warning {{non-type template argument referring to function 'f' with internal linkage is incompatible with C++98}} 337} 338 339namespace NullPointerTemplateArg { 340 struct A {}; 341 template<int*> struct X {}; 342 template<int A::*> struct Y {}; 343 X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} 344 Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}} 345} 346 347namespace PR13480 { 348 struct basic_iterator { 349 basic_iterator(const basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-provided copy constructor}} 350 basic_iterator(basic_iterator &it) {} 351 }; 352 353 union test { 354 basic_iterator it; // expected-warning {{union member 'it' with a non-trivial copy constructor is incompatible with C++98}} 355 }; 356} 357 358namespace AssignOpUnion { 359 struct a { 360 void operator=(const a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-provided copy assignment operator}} 361 void operator=(a &it) {} 362 }; 363 364 struct b { 365 void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}} 366 }; 367 368 union test1 { 369 a x; // expected-warning {{union member 'x' with a non-trivial copy assignment operator is incompatible with C++98}} 370 b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}} 371 }; 372} 373 374namespace rdar11736429 { 375 struct X { // expected-note {{because type 'rdar11736429::X' has no default constructor}} 376 X(const X&) = delete; // expected-warning{{deleted function definitions are incompatible with C++98}} \ 377 // expected-note {{implicit default constructor suppressed by user-declared constructor}} 378 }; 379 380 union S { 381 X x; // expected-warning{{union member 'x' with a non-trivial constructor is incompatible with C++98}} 382 }; 383} 384#endif 385 386template<typename T> T var = T(10); 387#ifdef CXX1YCOMPAT 388// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 389#else 390// expected-warning@-4 {{variable templates are a C++1y extension}} 391#endif 392 393template<typename T> T* var<T*> = new T(); 394#ifdef CXX1YCOMPAT 395// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 396#else 397// expected-warning@-4 {{variable templates are a C++1y extension}} 398#endif 399 400template<> int var<int> = 10; 401#ifdef CXX1YCOMPAT 402// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 403#else 404// expected-warning@-4 {{variable templates are a C++1y extension}} 405#endif 406 407template int var<int>; 408float fvar = var<float>; 409 410class A { 411 template<typename T> static T var = T(10); 412#ifdef CXX1YCOMPAT 413// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 414#else 415// expected-warning@-4 {{variable templates are a C++1y extension}} 416#endif 417 418 template<typename T> static T* var<T*> = new T(); 419#ifdef CXX1YCOMPAT 420// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 421#else 422// expected-warning@-4 {{variable templates are a C++1y extension}} 423#endif 424 425}; 426 427struct B { template<typename T> static T v; }; 428#ifdef CXX1YCOMPAT 429// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 430#else 431// expected-warning@-4 {{variable templates are a C++1y extension}} 432#endif 433 434template<typename T> T B::v = T(); 435#ifdef CXX1YCOMPAT 436// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 437#else 438// expected-warning@-4 {{variable templates are a C++1y extension}} 439#endif 440 441template<typename T> T* B::v<T*> = new T(); 442#ifdef CXX1YCOMPAT 443// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 444#else 445// expected-warning@-4 {{variable templates are a C++1y extension}} 446#endif 447 448template<> int B::v<int> = 10; 449#ifdef CXX1YCOMPAT 450// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}} 451#else 452// expected-warning@-4 {{variable templates are a C++1y extension}} 453#endif 454 455template int B::v<int>; 456float fsvar = B::v<float>; 457 458