diff options
Diffstat (limited to 'test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 126 |
1 files changed, 109 insertions, 17 deletions
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 09d93fa73af1..14c0ae320d77 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -95,11 +95,13 @@ namespace TemplateArgumentConversion { } namespace CaseStatements { + int x; void f(int n) { switch (n) { case MemberZero().zero: // expected-error {{did you mean to call it with no arguments?}} expected-note {{previous}} case id(0): // expected-error {{duplicate case value '0'}} return; + case __builtin_constant_p(true) ? (__SIZE_TYPE__)&x : 0:; // expected-error {{constant}} } } } @@ -602,7 +604,7 @@ struct A { constexpr A(int a, int b) : k(a + b) {} int k; }; constexpr int fn(const A &a) { return a.k; } static_assert(fn(A(4,5)) == 9, ""); -struct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}} +struct B { int n; int m; } constexpr b = { 0, b.n }; struct C { constexpr C(C *this_) : m(42), n(this_->m) {} // ok int m, n; @@ -1177,7 +1179,7 @@ namespace ExternConstexpr { void f() { extern constexpr int i; // expected-error {{constexpr variable declaration must be a definition}} constexpr int j = 0; - constexpr int k; // expected-error {{default initialization of an object of const type}} + constexpr int k; // expected-error {{default initialization of an object of const type}} expected-note{{add an explicit initializer to initialize 'k'}} } } @@ -1326,6 +1328,49 @@ namespace MutableMembers { struct C { B b; }; constexpr C c[3] = {}; constexpr int k = c[1].b.a.n; // expected-error {{constant expression}} expected-note {{mutable}} + + struct D { int x; mutable int y; }; // expected-note {{here}} + constexpr D d1 = { 1, 2 }; + int l = ++d1.y; + constexpr D d2 = d1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} + + struct E { + union { + int a; + mutable int b; // expected-note {{here}} + }; + }; + constexpr E e1 = {{1}}; + constexpr E e2 = e1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} + + struct F { + union U { }; + mutable U u; + struct X { }; + mutable X x; + struct Y : X { X x; U u; }; + mutable Y y; + int n; + }; + // This is OK; we don't actually read any mutable state here. + constexpr F f1 = {}; + constexpr F f2 = f1; + + struct G { + struct X {}; + union U { X a; }; + mutable U u; // expected-note {{here}} + }; + constexpr G g1 = {}; + constexpr G g2 = g1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} + constexpr G::U gu1 = {}; + constexpr G::U gu2 = gu1; + + union H { + mutable G::X gx; // expected-note {{here}} + }; + constexpr H h1 = {}; + constexpr H h2 = h1; // expected-error {{constant}} expected-note {{mutable}} expected-note {{in call}} } namespace Fold { @@ -1443,7 +1488,7 @@ namespace InvalidClasses { namespace NamespaceAlias { constexpr int f() { - namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++1y extension}} + namespace NS = NamespaceAlias; // expected-warning {{use of this statement in a constexpr function is a C++14 extension}} return &NS::f != nullptr; } } @@ -1568,7 +1613,8 @@ namespace TypeId { A &g(); constexpr auto &x = typeid(f()); constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \ - // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} + // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} \ + // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}} } namespace PR14203 { @@ -1667,6 +1713,9 @@ namespace InitializerList { return sum(ints.begin(), ints.end()); } static_assert(sum({1, 2, 3, 4, 5}) == 15, ""); + + static_assert(*std::initializer_list<int>{1, 2, 3}.begin() == 1, ""); + static_assert(std::initializer_list<int>{1, 2, 3}.begin()[2] == 3, ""); } namespace StmtExpr { @@ -1700,7 +1749,7 @@ namespace VirtualFromBase { template <typename T> struct X : T { constexpr X() {} double d = 0.0; - constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++1y}} + constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++14}} }; // Virtual f(), not OK. @@ -1715,17 +1764,17 @@ namespace VirtualFromBase { } namespace ConstexprConstructorRecovery { - class X { - public: - enum E : short { - headers = 0x1, - middlefile = 0x2, - choices = 0x4 - }; - constexpr X() noexcept {}; - protected: + class X { + public: + enum E : short { + headers = 0x1, + middlefile = 0x2, + choices = 0x4 + }; + constexpr X() noexcept {}; + protected: E val{0}; // expected-error {{cannot initialize a member subobject of type 'ConstexprConstructorRecovery::X::E' with an rvalue of type 'int'}} - }; + }; constexpr X x{}; } @@ -1799,8 +1848,9 @@ namespace ZeroSizeTypes { namespace BadDefaultInit { template<int N> struct X { static const int n = N; }; - struct A { // expected-note {{subexpression}} - int k = X<A().k>::n; // expected-error {{defaulted default constructor of 'A' cannot be used}} expected-error {{not a constant expression}} expected-note {{in call to 'A()'}} + struct A { + int k = // expected-error {{cannot use defaulted default constructor of 'A' within the class outside of member functions because 'k' has an initializer}} + X<A().k>::n; // expected-error {{not a constant expression}} expected-note {{implicit default constructor for 'BadDefaultInit::A' first required here}} }; // FIXME: The "constexpr constructor must initialize all members" diagnostic @@ -1892,3 +1942,45 @@ namespace PR19010 { }; void test() { constexpr Test t; } } + +void PR21327(int a, int b) { + static_assert(&a + 1 != &b, ""); // expected-error {{constant expression}} +} + +namespace EmptyClass { + struct E1 {} e1; + union E2 {} e2; // expected-note {{here}} + struct E3 : E1 {} e3; + + // The defaulted copy constructor for an empty class does not read any + // members. The defaulted copy constructor for an empty union reads the + // object representation. + constexpr E1 e1b(e1); + constexpr E2 e2b(e2); // expected-error {{constant expression}} expected-note{{read of non-const}} expected-note {{in call}} + constexpr E3 e3b(e3); +} + +namespace PR21786 { + extern void (*start[])(); + extern void (*end[])(); + static_assert(&start != &end, ""); // expected-error {{constant expression}} + static_assert(&start != nullptr, ""); + + struct Foo; + struct Bar { + static const Foo x; + static const Foo y; + }; + static_assert(&Bar::x != nullptr, ""); + static_assert(&Bar::x != &Bar::y, ""); +} + +namespace PR21859 { + constexpr int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}} + constexpr int Var = Fun(); // expected-error {{constexpr variable 'Var' must be initialized by a constant expression}} +} + +struct InvalidRedef { + int f; // expected-note{{previous definition is here}} + constexpr int f(void); // expected-error{{redefinition of 'f'}} expected-warning{{will not be implicitly 'const'}} +}; |