diff options
Diffstat (limited to 'test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp')
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp new file mode 100644 index 000000000000..03406dbf918a --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s + +namespace N { + typedef char C; +} + +namespace M { + typedef double D; +} + +struct NonLiteral { // expected-note 4{{no constexpr constructors}} + NonLiteral() {} + NonLiteral(int) {} +}; +struct Literal { + constexpr Literal() {} + operator int() const { return 0; } +}; + +struct S { + virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}} +}; +struct SS : S { + int ImplicitlyVirtual() const; +}; + +// Note, the wording applies constraints to the definition of constexpr +// functions, but we intentionally apply all that we can to the declaration +// instead. See DR1360. + +// The definition of a constexpr function shall satisfy the following +// constraints: +struct T : SS { // expected-note {{base class 'SS' of non-literal type}} + constexpr T(); // expected-error {{non-literal type 'T' cannot have constexpr members}} + + // - it shall not be virtual; + virtual constexpr int ExplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}} + + constexpr int ImplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}} + + // - its return type shall be a literal type; + constexpr NonLiteral NonLiteralReturn(); // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} + typedef NonLiteral F(); + constexpr F NonLiteralReturn2; // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + + // - each of its parameter types shall be a literal type; + constexpr int NonLiteralParam(NonLiteral); // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} + typedef int G(NonLiteral); + constexpr G NonLiteralParam2; // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} + + // - its function-body shall be = delete, = default, + constexpr int Deleted() = delete; + // It's not possible for the function-body to legally be "= default" here. + // Other than constructors, only the copy- and move-assignment operators and + // 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; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} +}; +struct U { + constexpr U SelfReturn(); + constexpr int SelfParam(U); +}; + +// or a compound-statememt that contains only +constexpr int AllowedStmts() { + // - null statements + ; + + // - static_assert-declarations + static_assert(true, "the impossible happened!"); + + // - typedef declarations and alias-declarations that do not define classes + // or enumerations + typedef int I; + typedef struct S T; + using J = int; + using K = int[sizeof(I) + sizeof(J)]; + // Note, the standard requires we reject this. + struct U; + + // - using-declarations + using N::C; + + // - using-directives + using namespace N; + + // - and exactly one return statement + return sizeof(K) + sizeof(C) + sizeof(K); +} +constexpr int ForStmt() { + for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int VarDecl() { + constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}} + return 0; +} +constexpr int FuncDecl() { + constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}} + return ForwardDecl(42); +} +constexpr int ClassDecl1() { + typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int ClassDecl2() { + using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int ClassDecl3() { + struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}} + return 0; +} +constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} +constexpr int MultiReturn() { + return 0; // expected-note {{return statement}} + return 0; // expected-error {{multiple return statements in constexpr function}} +} + +// - every constructor call and implicit conversion used in initializing the +// return value shall be one of those allowed in a constant expression. +// +// We implement the proposed resolution of DR1364 and ignore this bullet. |