diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/CXX/basic/basic.types/p10.cpp | 48 | ||||
-rw-r--r-- | test/CXX/class/class.static/class.static.data/p3.cpp | 7 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 8 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 25 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp | 14 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp | 42 | ||||
-rw-r--r-- | test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp | 6 | ||||
-rw-r--r-- | test/CXX/expr/expr.const/p2-0x.cpp | 19 | ||||
-rw-r--r-- | test/CXX/special/class.ctor/p6-0x.cpp | 6 | ||||
-rw-r--r-- | test/SemaCXX/constexpr-value-init.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/literal-type.cpp | 28 |
11 files changed, 104 insertions, 101 deletions
diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp index def4dc95bb..7641e09f61 100644 --- a/test/CXX/basic/basic.types/p10.cpp +++ b/test/CXX/basic/basic.types/p10.cpp @@ -5,22 +5,23 @@ struct NonLiteral { NonLiteral(); }; // A type is a literal type if it is: // - a scalar type -constexpr int f1(double); +constexpr int f1(double) { return 0; } // - a reference type struct S { S(); }; -constexpr int f2(S &); +constexpr int f2(S &) { return 0; } // - a class type that has all of the following properties: // - it has a trivial destructor struct UserProvDtor { - constexpr UserProvDtor(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} + constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} ~UserProvDtor(); // expected-note {{has a user-provided destructor}} }; struct NonTrivDtor { - constexpr NonTrivDtor(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} + constexpr NonTrivDtor(); + constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} }; struct NonTrivDtorBase { @@ -30,16 +31,16 @@ template<typename T> struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}} constexpr DerivedFromNonTrivDtor(); }; -constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}} +constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}} struct TrivDtor { constexpr TrivDtor(); }; -constexpr int f(TrivDtor); +constexpr int f(TrivDtor) { return 0; } struct TrivDefaultedDtor { constexpr TrivDefaultedDtor(); ~TrivDefaultedDtor() = default; }; -constexpr int f(TrivDefaultedDtor); +constexpr int f(TrivDefaultedDtor) { return 0; } // - it is an aggregate type or has at least one constexpr constructor or // constexpr constructor template that is not a copy or move constructor @@ -52,36 +53,41 @@ struct CtorTemplate { template<typename T> constexpr CtorTemplate(T); }; struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} - constexpr CopyCtorOnly(CopyCtorOnly&); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} + constexpr CopyCtorOnly(CopyCtorOnly&); + constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} }; struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} - constexpr MoveCtorOnly(MoveCtorOnly&&); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} + constexpr MoveCtorOnly(MoveCtorOnly&&); + constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} }; template<typename T> -struct CtorArg { // expected-note {{no constexpr constructors other than copy or move constructors}} - constexpr CtorArg(T); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} +struct CtorArg { + constexpr CtorArg(T); }; -constexpr int f(CtorArg<int>); -constexpr int f(CtorArg<NonLiteral>); // expected-error {{not a literal type}} +constexpr int f(CtorArg<int>) { return 0; } // ok +constexpr int f(CtorArg<NonLiteral>) { return 0; } // ok, ctor is still constexpr // We have a special-case diagnostic for classes with virtual base classes. struct VBase {}; struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}} struct Derived : HasVBase { - constexpr Derived(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}} + constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} }; template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}} constexpr DerivedFromVBase(); }; -constexpr int f(DerivedFromVBase<HasVBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}} +constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}} +template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {} +constexpr int nVBase = (DerivedFromVBase<HasVBase>(), 0); // expected-error {{constant expression}} expected-note {{cannot construct object of type 'DerivedFromVBase<HasVBase>' with virtual base class in a constant expression}} // - it has all non-static data members and base classes of literal types struct NonLitMember { S s; // expected-note {{has data member 's' of non-literal type 'S'}} }; -constexpr int f(NonLitMember); // expected-error {{1st parameter type 'NonLitMember' is not a literal type}} +constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}} struct NonLitBase : S { // expected-note {{base class 'S' of non-literal type}} - constexpr NonLitBase(); // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} + constexpr NonLitBase(); + constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} }; struct LitMemBase : Agg { Agg agg; @@ -91,8 +97,8 @@ struct MemberType { T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}} constexpr MemberType(); }; -constexpr int f(MemberType<int>); -constexpr int f(MemberType<NonLiteral>); // expected-error {{not a literal type}} +constexpr int f(MemberType<int>) { return 0; } +constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}} // - an array of literal type struct ArrGood { @@ -101,9 +107,9 @@ struct ArrGood { TrivDtor td[3]; TrivDefaultedDtor tdd[3]; }; -constexpr int f(ArrGood); +constexpr int f(ArrGood) { return 0; } struct ArrBad { S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} }; -constexpr int f(ArrBad); // expected-error {{1st parameter type 'ArrBad' is not a literal type}} +constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}} diff --git a/test/CXX/class/class.static/class.static.data/p3.cpp b/test/CXX/class/class.static/class.static.data/p3.cpp index fed715e219..fef9a7dae1 100644 --- a/test/CXX/class/class.static/class.static.data/p3.cpp +++ b/test/CXX/class/class.static/class.static.data/p3.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -struct NonLit { +struct NonLit { // expected-note {{no constexpr constructors}} NonLit(); }; @@ -29,15 +29,14 @@ template<typename T> struct U { static constexpr int a = 0; static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}} - // FIXME: It'd be nice to error on this at template definition time. - static constexpr NonLit h = NonLit(); // expected-error 2{{must be initialized by a constant expression}} expected-note 2{{non-literal type}} + static constexpr NonLit h = NonLit(); // expected-error {{cannot have non-literal type 'const NonLit'}} static constexpr T c = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type}} static const T d; }; template<typename T> constexpr T U<T>::d = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type 'const NonLit'}} -U<int> u1; // expected-note {{here}} +U<int> u1; U<NonLit> u2; // expected-note {{here}} static_assert(U<int>::a == 0, ""); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp index f173748e96..24e15e3d78 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -struct notlit { +struct notlit { // expected-note {{not literal because}} notlit() {} }; struct notlit2 { @@ -20,7 +20,7 @@ constexpr int s1::mi2 = 0; // not a definition of an object constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}} // not a literal type -constexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}} expected-note {{non-literal type 'const notlit' cannot be used in a constant expression}} +constexpr notlit nl1; // expected-error {{constexpr variable cannot have non-literal type 'const notlit'}} // function parameters void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}} // non-static member @@ -77,11 +77,11 @@ struct S { // explicit specialization can differ in constepxr // FIXME: When checking the explicit specialization, we implicitly instantiate // the primary template then claim a constexpr mismatch. -template <> notlit ft(notlit nl) { return nl; } +template <> notlit ft(notlit nl) { return nl; } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}} template <> char ft(char c) { return c; } // desired-note {{previous}} unexpected-error {{follows constexpr declaration}} unexpected-note {{here}} template <> constexpr char ft(char nl); // desired-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}} template <> constexpr int gt(int nl) { return nl; } // unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}} -template <> notlit S::f() const { return notlit(); } +template <> notlit S::f() const { return notlit(); } // unexpected-error {{follows constexpr declaration}} unexpected-note {{here}} template <> constexpr int S::g() { return 0; } // desired-note {{previous}} unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}} template <> int S::g() const; // desired-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}} // specializations can drop the 'constexpr' but not the implied 'const'. diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index 19bcde6640..cafdd63551 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -8,7 +8,7 @@ namespace M { typedef double D; } -struct NonLiteral { // expected-note 4{{no constexpr constructors}} +struct NonLiteral { // expected-note 2{{no constexpr constructors}} NonLiteral() {} NonLiteral(int) {} }; @@ -24,31 +24,28 @@ 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, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} - constexpr T(); // expected-error {{non-literal type 'T' cannot have constexpr members}} + constexpr T(); + constexpr int f(); // 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}} + virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} - constexpr int ImplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}} + constexpr int ImplicitlyVirtual() { return 0; } // 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 void VoidReturn(); // expected-error {{constexpr function's return type 'void' is not a literal type}} + constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' 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}} + constexpr F NonLiteralReturn2; // ok until definition // - 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}} + constexpr int NonLiteralParam(NonLiteral) { return 0; } // 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}} + constexpr G NonLiteralParam2; // ok until definition // - its function-body shall be = delete, = default, constexpr int Deleted() = delete; @@ -65,7 +62,7 @@ struct U { }; struct V : virtual U { // expected-note {{here}} - constexpr int F(); // expected-error {{constexpr member function not allowed in struct with virtual base class}} + constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} }; // or a compound-statememt that contains only diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index 86b7ded959..65573c7533 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -18,16 +18,12 @@ struct Literal { operator int() const { return 0; } }; -// Note, the wording applies constraints to the definition of constexpr -// constructors, but we intentionally apply all that we can to the declaration -// instead. See DR1360. - // In the definition of a constexpr constructor, each of the parameter types // shall be a literal type. struct S { - constexpr S(int, N::C); - constexpr S(int, NonLiteral, N::C); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} - constexpr S(int, NonLiteral = 42); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} + constexpr S(int, N::C) {} + constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} + constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} // In addition, either its function-body shall be = delete or = default constexpr S() = default; @@ -38,14 +34,14 @@ struct S { // - the class shall not have any virtual base classes; struct T : virtual S { // expected-note {{here}} - constexpr T(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}} + constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} }; namespace IndirectVBase { struct A {}; struct B : virtual A {}; // expected-note {{here}} class C : public B { public: - constexpr C(); // expected-error {{constexpr constructor not allowed in class with virtual base class}} + constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}} }; } diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp index e383bc0922..1a6dc9ecfb 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp @@ -10,7 +10,7 @@ namespace M { struct NonLiteral { NonLiteral() {} - NonLiteral(int) {} + NonLiteral(int) {} // expected-note 2{{here}} operator int() const { return 0; } }; struct Literal { @@ -19,7 +19,7 @@ struct Literal { }; struct S { - virtual int ImplicitlyVirtual(); + virtual int ImplicitlyVirtual() const; }; struct T {}; @@ -27,48 +27,42 @@ template<typename T> struct ImplicitVirtualFromDependentBase : T { constexpr int ImplicitlyVirtual() { return 0; } }; -// FIXME: Can't test this until we have function invocation substitution -#if 0 -constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // desired-error {{not a constant expression}} +constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}} constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // ok -#endif +constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual(); template<typename R> struct ConstexprMember { constexpr R F() { return 0; } }; -// FIXME: Can't test this until we have function invocation substitution -#if 0 -constexpr int c = ConstexprMember<int>().F(); // ok -constexpr int d = ConstexprMember<NonLiteral>().F(); // desired-error {{not a constant expression}} -#endif +constexpr int d = ConstexprMember<int>().F(); // ok +constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} -template<typename ...P> struct ConstexprCtor { // expected-note 2{{no constexpr constructors}} - constexpr ConstexprCtor(P...); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} \ - expected-note {{constructor template instantiation is not constexpr because 2nd parameter type 'NonLiteral' is not a literal type}} +template<typename ...P> struct ConstexprCtor { + constexpr ConstexprCtor(P...) {} }; -constexpr ConstexprCtor<> f1(); // ok -constexpr ConstexprCtor<int> f2(); // ok -constexpr ConstexprCtor<NonLiteral> f3(); // expected-error {{not a literal type}} -constexpr ConstexprCtor<int, NonLiteral> f4(); // expected-error {{not a literal type}} +constexpr ConstexprCtor<> f1() { return {}; } // ok +constexpr ConstexprCtor<int> f2() { return 0; } // ok +constexpr ConstexprCtor<NonLiteral> f3() { return { 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}} +constexpr ConstexprCtor<int, NonLiteral> f4() { return { 0, 0 }; } // expected-error {{never produces a constant expression}} expected-note {{non-constexpr constructor 'NonLiteral}} struct VirtBase : virtual S {}; // expected-note {{here}} namespace TemplateVBase { template<typename T> struct T1 : virtual Literal { // expected-note {{here}} - constexpr T1(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}} + constexpr T1() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} }; - template<typename T> struct T2 : virtual T { // expected-note {{struct with virtual base class is not a literal type}} expected-note {{here}} + template<typename T> struct T2 : virtual T { // FIXME: This is ill-formed (no diagnostic required). // We should diagnose it now rather than waiting until instantiation. - constexpr T2(); // desired-error {{constexpr constructor not allowed in class with virtual base classes}} + constexpr T2() {} }; - constexpr T2<Literal> g2(); // expected-error {{not a literal type}} + constexpr T2<Literal> g2() { return {}; } template<typename T> class T3 : public T { // expected-note {{class with virtual base class is not a literal type}} public: constexpr T3() {} }; - constexpr T3<Literal> g3(); // ok - constexpr T3<VirtBase> g4(); // expected-error {{not a literal type}} + constexpr T3<Literal> g3() { return {}; } // ok + constexpr T3<VirtBase> g4() { return {}; } // expected-error {{not a literal type}} } diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp index 34114cb077..2412a145f8 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp @@ -18,15 +18,15 @@ extern int (*const d)(int); // A variable declaration which uses the constexpr specifier shall have an // initializer and shall be initialized by a constant expression. constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}} -constexpr struct C { C(); } ni2; // expected-error {{constexpr variable 'ni2' must be initialized by a constant expression}} expected-note {{non-literal type 'const struct C' cannot be used in a constant expression}} +constexpr struct C { C(); } ni2; // expected-error {{cannot have non-literal type 'const struct C'}} expected-note 3{{has no constexpr constructors}} constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}} constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} -constexpr C nc2 = C(); // expected-error {{constexpr variable 'nc2' must be initialized by a constant expression}} expected-note {{non-literal type}} +constexpr C nc2 = C(); // expected-error {{cannot have non-literal type 'const C'}} int &f(); // expected-note {{declared here}} constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}} constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} expected-note {{read of non-const variable 'i' is not allowed in a constant expression}} -constexpr C nc5((C())); // expected-error {{constexpr variable 'nc5' must be initialized by a constant expression}} expected-note {{non-literal type 'const C'}} +constexpr C nc5((C())); // expected-error {{cannot have non-literal type 'const C'}} int &f(); // expected-note {{here}} constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}} diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index 2d4f4fb62e..a22d1e4e4e 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -288,7 +288,7 @@ namespace LValueToRValue { // non-volatile const object with a preceding initialization, initialized // with a constant expression [Note: a string literal (2.14.5 [lex.string]) // corresponds to an array of such objects. -end note], or - volatile const int vi = 1; // expected-note {{here}} + volatile const int vi = 1; // expected-note 2{{here}} const int ci = 1; volatile const int &vrci = ci; static_assert(vi, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} @@ -298,18 +298,23 @@ namespace LValueToRValue { // - a non-volatile glvalue of literal type that refers to a non-volatile // object defined with constexpr, or that refers to a sub-object of such an // object, or + struct V { + constexpr V() : v(1) {} + volatile int v; // expected-note {{not literal because}} + }; + constexpr V v; // expected-error {{non-literal type}} struct S { - constexpr S(int=0) : i(1), v(1) {} - constexpr S(const S &s) : i(2), v(2) {} + constexpr S(int=0) : i(1), v(const_cast<volatile int&>(vi)) {} + constexpr S(const S &s) : i(2), v(const_cast<volatile int&>(vi)) {} int i; - volatile int v; // expected-note {{here}} + volatile int &v; }; - constexpr S s; + constexpr S s; // ok constexpr volatile S vs; // expected-note {{here}} - constexpr const volatile S &vrs = s; + constexpr const volatile S &vrs = s; // ok static_assert(s.i, ""); static_assert(s.v, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} - static_assert(const_cast<int&>(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile member 'v'}} + static_assert(const_cast<int&>(s.v), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vi'}} static_assert(vs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} static_assert(const_cast<int&>(vs.i), ""); // expected-error {{constant expression}} expected-note {{read of volatile object 'vs'}} static_assert(vrs.i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}} diff --git a/test/CXX/special/class.ctor/p6-0x.cpp b/test/CXX/special/class.ctor/p6-0x.cpp index 71afd244bd..8c8800f2de 100644 --- a/test/CXX/special/class.ctor/p6-0x.cpp +++ b/test/CXX/special/class.ctor/p6-0x.cpp @@ -11,7 +11,7 @@ struct NonConstexpr2 { // expected-note {{here}} struct NonConstexpr2a : NonConstexpr1 { }; constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor -constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr2a'}} +constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor constexpr int nc2_a = NonConstexpr2().nl.a; // ok constexpr int nc2a_a = NonConstexpr2a().a; // ok struct Helper { @@ -21,8 +21,8 @@ struct Helper { struct Constexpr1 {}; constexpr Constexpr1 c1 = Constexpr1(); // ok -struct NonConstexpr3 : virtual Constexpr1 {}; -constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr3'}} +struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}} +constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}} struct Constexpr2 { int a = 0; diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp index efa9e94da1..db4b68dcc6 100644 --- a/test/SemaCXX/constexpr-value-init.cpp +++ b/test/SemaCXX/constexpr-value-init.cpp @@ -26,6 +26,6 @@ struct D : C { int d; }; constexpr C c1; // expected-error {{requires a user-provided default constructor}} constexpr C c2 = C(); // ok constexpr D d1; // expected-error {{requires a user-provided default constructor}} -constexpr D d2 = D(); // expected-error {{constant expression}} expected-note {{non-literal type 'const D'}} +constexpr D d2 = D(); // ok with DR1452 static_assert(D().c == 0, ""); static_assert(D().d == 0, ""); diff --git a/test/SemaCXX/literal-type.cpp b/test/SemaCXX/literal-type.cpp index 60bfcf00cf..14a4094c45 100644 --- a/test/SemaCXX/literal-type.cpp +++ b/test/SemaCXX/literal-type.cpp @@ -23,6 +23,8 @@ static_assert(__is_literal(VectorExt), "fail"); // a constant expression, // -- it is an aggregate type or has at least one constexpr constructor // or constructor template that is not a copy or move constructor, and +// [DR1452 adds class types with trivial default constructors to +// this list] // -- it has all non-static data members and base classes of literal // types struct Empty {}; @@ -36,25 +38,26 @@ struct LiteralType { struct HasDtor { ~HasDtor(); }; class NonAggregate { int x; }; -struct HasNonLiteralBase : NonAggregate {}; +struct NonLiteral { NonLiteral(); }; +struct HasNonLiteralBase : NonLiteral {}; struct HasNonLiteralMember { HasDtor x; }; static_assert(__is_literal(Empty), "fail"); static_assert(__is_literal(LiteralType), "fail"); +static_assert(__is_literal(NonAggregate), "fail"); +static_assert(!__is_literal(NonLiteral), "fail"); static_assert(!__is_literal(HasDtor), "fail"); -static_assert(!__is_literal(NonAggregate), "fail"); static_assert(!__is_literal(HasNonLiteralBase), "fail"); static_assert(!__is_literal(HasNonLiteralMember), "fail"); -// FIXME: Test constexpr constructors and non-static members with initializers -// when Clang supports them: -#if 0 -extern int f(); +// DR1361 removes the brace-or-equal-initializer bullet so that we can allow: +extern int f(); // expected-note {{here}} struct HasNonConstExprMemInit { - int x = f(); - constexpr HasNonConstExprMemInit(int y) {} + int x = f(); // expected-note {{non-constexpr function}} + constexpr HasNonConstExprMemInit() {} // expected-error {{never produces a constant expression}} + constexpr HasNonConstExprMemInit(int y) : x(y) {} // ok }; -static_assert(!__is_literal(HasNonConstExprMemInit), "fail"); +static_assert(__is_literal(HasNonConstExprMemInit), "fail"); class HasConstExprCtor { int x; @@ -66,6 +69,9 @@ template <typename T> class HasConstExprCtorTemplate { public: template <typename U> constexpr HasConstExprCtorTemplate(U y) : x(y) {} }; +template <typename T> class HasConstExprCtorT { + constexpr HasConstExprCtorT(T) {} +}; static_assert(__is_literal(HasConstExprCtor), "fail"); -static_assert(__is_literal(HasConstExprCtorTemplate), "fail"); -#endif +static_assert(__is_literal(HasConstExprCtorTemplate<int>), "fail"); +static_assert(__is_literal(HasConstExprCtorT<NonLiteral>), "fail"); |