diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++14-extensions -Werror=c++20-extensions -Werror=c++2b-extensions %s -// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++14 -DCXX14 -Werror=c++20-extensions -Werror=c++2b-extensions %s -// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++20 -DCXX14 -DCXX20 -Werror=c++2b-extensions %s -// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++2b -DCXX14 -DCXX20 -DCXX2b %s +// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,beforecxx14,beforecxx20,beforecxx2b -std=c++11 %s +// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,beforecxx20,beforecxx2b -std=c++14 %s +// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20,beforecxx2b -std=c++20 %s +// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20 -std=c++2b %s namespace N { typedef char C; @@ -21,10 +21,7 @@ }; struct S { - virtual int ImplicitlyVirtual() const = 0; -#if __cplusplus <= 201703L - // expected-note@-2 {{overridden virtual function}} -#endif + virtual int ImplicitlyVirtual() const = 0; // beforecxx20-note {{overridden virtual function}} }; struct SS : S { int ImplicitlyVirtual() const; @@ -37,31 +34,17 @@ constexpr int f() const; // - it shall not be virtual; [until C++20] - virtual constexpr int ExplicitlyVirtual() const { return 0; } -#if __cplusplus <= 201703L - // expected-error@-2 {{virtual function cannot be constexpr}} -#endif + virtual constexpr int ExplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}} - constexpr int ImplicitlyVirtual() const { return 0; } -#if __cplusplus <= 201703L - // expected-error@-2 {{virtual function cannot be constexpr}} -#endif + constexpr int ImplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}} - virtual constexpr int OutOfLineVirtual() const; -#if __cplusplus <= 201703L - // expected-error@-2 {{virtual function cannot be constexpr}} -#endif + virtual constexpr int OutOfLineVirtual() const; // beforecxx20-error {{virtual function cannot be constexpr}} // - its return type shall be a literal type; constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} - constexpr void VoidReturn() const { return; } -#ifndef CXX14 - // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}} -#endif - constexpr ~T(); -#ifndef CXX20 - // expected-error@-2 {{destructor cannot be declared constexpr}} -#endif + constexpr void VoidReturn() const { return; } // beforecxx14-error {{constexpr function's return type 'void' is not a literal type}} + constexpr ~T(); // beforecxx20-error {{destructor cannot be declared constexpr}} + typedef NonLiteral F() const; constexpr F NonLiteralReturn2; // ok until definition @@ -78,29 +61,21 @@ // destructor can be defaulted. Destructors can't be constexpr since they // don't have a literal return type. Defaulted assignment operators can't be // constexpr since they can't be const. - constexpr T &operator=(const T&) = default; -#ifndef CXX14 - // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} - // expected-warning@-3 {{C++14}} -#else - // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}} -#endif + constexpr T &operator=(const T &) = default; // beforecxx14-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} \ + // beforecxx14-warning {{C++14}} \ + // aftercxx14-error{{defaulted definition of copy assignment operator is not constexpr}} }; constexpr int T::OutOfLineVirtual() const { return 0; } -#ifdef CXX14 +#if __cplusplus >= 201402L struct T2 { int n = 0; constexpr T2 &operator=(const T2&) = default; // ok }; struct T3 { - constexpr T3 &operator=(const T3&) const = default; -#ifndef CXX20 - // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} -#else - // expected-warning@-4 {{explicitly defaulted copy assignment operator is implicitly deleted}} - // expected-note@-5 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}} -#endif + constexpr T3 &operator=(const T3 &) const = default; // beforecxx20-error {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} \ + // aftercxx20-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} \ + // aftercxx20-note {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}} }; #endif struct U { @@ -143,157 +118,101 @@ constexpr int DisallowedStmtsCXX14_1(bool b) { // - an asm-definition if (b) - asm("int3"); -#if !defined(CXX20) - // expected-error@-2 {{use of this statement in a constexpr function is a C++20 extension}} -#endif + asm("int3"); // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}} return 0; } constexpr int DisallowedStmtsCXX14_2() { + return 0; // beforecxx14-note {{previous}} // - a goto statement - try { - } catch (...) { - goto x; + goto x; // beforecxx2b-warning {{use of this statement in a constexpr function is a C++2b extension}} x:; - } -#ifndef CXX2b - // expected-error@-4 {{use of this statement in a constexpr function is a C++2b extension}} -#endif - return 0; + return 0; // beforecxx14-warning {{multiple return}} } constexpr int DisallowedStmtsCXX14_2_1() { - try { - } catch (...) { - merp: - goto merp; -#ifndef CXX2b - // expected-error@-3 {{use of this statement in a constexpr function is a C++2b extension}} -#endif - } +merp: // beforecxx2b-warning {{use of this statement in a constexpr function is a C++2b extension}} return 0; } constexpr int DisallowedStmtsCXX14_3() { // - a try-block, - try {} catch (...) {} -#if !defined(CXX20) - // expected-error@-2 {{use of this statement in a constexpr function is a C++20 extension}} -#endif + try { } // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}} + catch (...) {} return 0; } constexpr int DisallowedStmtsCXX14_4() { // - a definition of a variable of non-literal type return 0; - NonLiteral nl; -#ifndef CXX2b - // expected-error@-2 {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} - // expected-note@14 {{'NonLiteral' is not literal}} -#endif + NonLiteral nl; // beforecxx2b-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++2b}} \ + // beforecxx2b-note@14 {{'NonLiteral' is not literal}} } constexpr int DisallowedStmtsCXX14_5() { return 0; // - a definition of a variable of static storage duration - static constexpr int n = 123; -#ifndef CXX2b - // expected-error@-2 {{definition of a static variable in a constexpr function is a C++2b extension}} -#endif -#if !defined(CXX14) - // expected-error@-5 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + static constexpr int n = 123; // beforecxx2b-warning {{definition of a static variable in a constexpr function is a C++2b extension}} \ + // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} } + constexpr int DisallowedStmtsCXX14_6() { // - a definition of a variable of thread storage duration return 0; - thread_local constexpr int n = 123; -#ifndef CXX2b - // expected-error@-2 {{definition of a thread_local variable in a constexpr function is a C++2b extension}} -#endif -#if !defined(CXX14) - // expected-error@-5 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + thread_local constexpr int n = 123; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} \ + // beforecxx2b-warning {{definition of a thread_local variable in a constexpr function is a C++2b extension}} } constexpr int DisallowedStmtsCXX14_7() { // - a definition of a variable for which no initialization is performed - int n; -#ifndef CXX20 - // expected-error@-2 {{uninitialized variable in a constexpr function}} -#endif return 0; + int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}} } constexpr int ForStmt() { - for (int n = 0; n < 10; ++n) -#ifndef CXX14 - // expected-error@-2 {{statement not allowed in constexpr function}} -#endif + for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}} return 0; } + constexpr int VarDecl() { - int a = 0; -#ifndef CXX14 - // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} return 0; } constexpr int ConstexprVarDecl() { - constexpr int a = 0; -#ifndef CXX14 - // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + constexpr int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} return 0; } constexpr int VarWithCtorDecl() { - Literal a; -#ifndef CXX14 - // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + Literal a; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} return 0; } + NonLiteral nl; constexpr NonLiteral &ExternNonLiteralVarDecl() { - extern NonLiteral nl; -#ifndef CXX14 - // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + extern NonLiteral nl; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} return nl; } static_assert(&ExternNonLiteralVarDecl() == &nl, ""); + constexpr int FuncDecl() { - constexpr int ForwardDecl(int); -#ifndef CXX14 - // expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}} -#endif + constexpr int ForwardDecl(int); // beforecxx14-warning {{use of this statement in a constexpr function is a C++14 extension}} return ForwardDecl(42); } + constexpr int ClassDecl1() { - typedef struct { } S1; -#ifndef CXX14 - // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} -#endif + typedef struct {} S1; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}} return 0; } + constexpr int ClassDecl2() { - using S2 = struct { }; -#ifndef CXX14 - // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} -#endif + using S2 = struct {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}} return 0; } + constexpr int ClassDecl3() { - struct S3 { }; -#ifndef CXX14 - // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} -#endif + struct S3 {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}} return 0; } + constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} constexpr int MultiReturn() { - return 0; - return 0; -#ifndef CXX14 - // expected-error@-2 {{multiple return statements in constexpr function}} - // expected-note@-4 {{return statement}} -#endif + return 0; // beforecxx14-note {{return statement}} + return 0; // beforecxx14-warning {{multiple return statements in constexpr function}} } // - every constructor call and implicit conversion used in initializing the @@ -309,7 +228,7 @@ } int kGlobal; // expected-note {{here}} constexpr int f() { // expected-error {{constexpr function never produces a constant expression}} - return kGlobal; // expected-note {{read of non-const}} + return kGlobal; // expected-note {{read of non-const}} } } @@ -337,44 +256,27 @@ return 2147483647; } constexpr int abs(int x) { - if (x < 0) -#ifndef CXX14 - // expected-error@-2 {{C++14}} -#endif + if (x < 0) // beforecxx14-warning {{C++14}} x = -x; return x; } constexpr int first(int n) { return 0; - static int value = n; -#ifndef CXX2b - // expected-error@-2 {{definition of a static variable in a constexpr function is a C++2b extension}} -#endif -#ifndef CXX14 - // expected-error@-5 {{variable declaration in a constexpr function is a C++14 extension}} -#endif + static int value = n; // beforecxx2b-warning {{definition of a static variable in a constexpr function is a C++2b extension}} \ + // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} } constexpr int uninit() { - int a; -#ifndef CXX20 - // expected-error@-2 {{uninitialized}} -#endif + int a; // beforecxx20-warning {{uninitialized}} return a; } - constexpr int prev(int x) { - return --x; + constexpr int prev(int x) { // beforecxx14-error {{never produces a constant expression}} + return --x; // beforecxx14-note {{subexpression}} } -#ifndef CXX14 - // expected-error@-4 {{never produces a constant expression}} - // expected-note@-4 {{subexpression}} -#endif + constexpr int g(int x, int n) { - int r = 1; - while (--n > 0) r *= x; + int r = 1; // beforecxx14-warning{{C++14}} + while (--n > 0) // beforecxx14-error {{statement not allowed in constexpr function}} + r *= x; return r; } -#ifndef CXX14 - // expected-error@-5 {{C++14}} - // expected-error@-5 {{statement not allowed}} -#endif }