blob: 03406dbf918a4297c370f4476896c58abc8966da [file] [log] [blame]
// 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.