aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/constant-expression-cxx11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r--test/SemaCXX/constant-expression-cxx11.cpp126
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'}}
+};