summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/expr/expr.const/p2-0x.cpp4
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp76
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx1y.cpp46
3 files changed, 12 insertions, 114 deletions
diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp
index 2496845182f..4daed23bf9c 100644
--- a/clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -210,8 +210,8 @@ namespace UndefinedBehavior {
constexpr int f() const { return 0; }
} constexpr c = C();
constexpr int k1 = c.f(); // ok
- constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced null pointer}}
- constexpr int k3 = (&c)[1].f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced one-past-the-end pointer}}
+ constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{cannot call member function on null pointer}}
+ constexpr int k3 = (&c)[1].f(); // expected-error {{constant expression}} expected-note {{cannot call member function on pointer past the end of object}}
C c2;
constexpr int k4 = c2.f(); // ok!
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index c136b4d2693..6af43854b52 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -192,25 +192,6 @@ namespace StaticMemberFunction {
constexpr int (*sf1)(int) = &S::f;
constexpr int (*sf2)(int) = &s.f;
constexpr const int *sk = &s.k;
-
- // Note, out_of_lifetime returns an invalid pointer value, but we don't do
- // anything with it (other than copy it around), so there's no UB there.
- constexpr S *out_of_lifetime(S s) { return &s; } // expected-warning {{address of stack}}
- static_assert(out_of_lifetime({})->k == 42, "");
- static_assert(out_of_lifetime({})->f(3) == 128, "");
-
- // Similarly, using an inactive union member breaks no rules.
- union U {
- int n;
- S s;
- };
- constexpr U u = {0};
- static_assert(u.s.k == 42, "");
- static_assert(u.s.f(1) == 44, "");
-
- // And likewise for a past-the-end pointer.
- static_assert((&s)[1].k == 42, "");
- static_assert((&s)[1].f(1) == 44, "");
}
namespace ParameterScopes {
@@ -1748,10 +1729,19 @@ namespace PR14203 {
constexpr duration() {}
constexpr operator int() const { return 0; }
};
- // These are valid per P0859R0 (moved as DR).
template<typename T> void f() {
+ // If we want to evaluate this at the point of the template definition, we
+ // need to trigger the implicit definition of the move constructor at that
+ // point.
+ // FIXME: C++ does not permit us to implicitly define it at the appropriate
+ // times, since it is only allowed to be implicitly defined when it is
+ // odr-used.
constexpr duration d = duration();
}
+ // FIXME: It's unclear whether this is valid. On the one hand, we're not
+ // allowed to generate a move constructor. On the other hand, if we did,
+ // this would be a constant expression. For now, we generate a move
+ // constructor here.
int n = sizeof(short{duration(duration())});
}
@@ -1912,52 +1902,6 @@ namespace Lifetime {
};
constexpr int k1 = S().t; // expected-error {{constant expression}} expected-note {{in call}}
constexpr int k2 = S(0).t; // expected-error {{constant expression}} expected-note {{in call}}
-
- struct Q {
- int n = 0;
- constexpr int f() const { return 0; }
- };
- constexpr Q *out_of_lifetime(Q q) { return &q; } // expected-warning {{address of stack}} expected-note 2{{declared here}}
- constexpr int k3 = out_of_lifetime({})->n; // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}}
- constexpr int k4 = out_of_lifetime({})->f(); // expected-error {{constant expression}} expected-note {{member call on variable whose lifetime has ended}}
-
- constexpr int null = ((Q*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced null pointer}}
-
- Q q;
- Q qa[3];
- constexpr int pte0 = (&q)[0].f(); // ok
- constexpr int pte1 = (&q)[1].f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced one-past-the-end pointer}}
- constexpr int pte2 = qa[2].f(); // ok
- constexpr int pte3 = qa[3].f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced one-past-the-end pointer}}
-
- constexpr Q cq;
- constexpr Q cqa[3];
- constexpr int cpte0 = (&cq)[0].f(); // ok
- constexpr int cpte1 = (&cq)[1].f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced one-past-the-end pointer}}
- constexpr int cpte2 = cqa[2].f(); // ok
- constexpr int cpte3 = cqa[3].f(); // expected-error {{constant expression}} expected-note {{member call on dereferenced one-past-the-end pointer}}
-
- // FIXME: There's no way if we can tell if the first call here is valid; it
- // depends on the active union member. Should we reject for that reason?
- union U {
- int n;
- Q q;
- };
- U u1 = {0};
- constexpr U u2 = {0};
- constexpr int union_member1 = u1.q.f();
- constexpr int union_member2 = u2.q.f(); // expected-error {{constant expression}} expected-note {{member call on member 'q' of union with active member 'n'}}
-
- struct R { // expected-note {{field init}}
- struct Inner { constexpr int f() const { return 0; } };
- int a = b.f(); // expected-warning {{uninitialized}} expected-note {{member call on object outside its lifetime}}
- Inner b;
- };
- // FIXME: This should be rejected under DR2026.
- constexpr R r; // expected-note {{default constructor}}
- void rf() {
- constexpr R r; // expected-error {{constant expression}} expected-note {{in call}}
- }
}
namespace Bitfields {
diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
index fe69d105023..07ef7974d11 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1159,49 +1159,3 @@ enum InEnum2 : int {
enum class InEnum3 {
THREE = indirect_builtin_constant_p("abc")
};
-
-// [class.ctor]p4:
-// A constructor can be invoked for a const, volatile or const volatile
-// object. const and volatile semantics are not applied on an object under
-// construction. They come into effect when the constructor for the most
-// derived object ends.
-namespace ObjectsUnderConstruction {
- struct A {
- int n;
- constexpr A() : n(1) { n = 2; }
- };
- struct B {
- const A a;
- constexpr B(bool mutate) {
- if (mutate)
- const_cast<A &>(a).n = 3; // expected-note {{modification of object of const-qualified type 'const int'}}
- }
- };
- constexpr B b(false);
- static_assert(b.a.n == 2, "");
- constexpr B bad(true); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'B(true)'}}
-
- struct C {
- int n;
- constexpr C() : n(1) { n = 2; }
- };
- constexpr int f(bool get) {
- volatile C c; // expected-note {{here}}
- return get ? const_cast<int&>(c.n) : 0; // expected-note {{read of volatile object 'c'}}
- }
- static_assert(f(false) == 0, ""); // ok, can modify volatile c.n during c's initialization: it's not volatile then
- static_assert(f(true) == 2, ""); // expected-error {{constant}} expected-note {{in call}}
-
- struct Aggregate {
- int x = 0;
- int y = ++x;
- };
- constexpr Aggregate aggr1;
- static_assert(aggr1.x == 1 && aggr1.y == 1, "");
- // FIXME: This is not specified by the standard, but sanity requires it.
- constexpr Aggregate aggr2 = {};
- static_assert(aggr2.x == 1 && aggr2.y == 1, "");
-
- // The lifetime of 'n' begins at the initialization, not before.
- constexpr int n = ++const_cast<int&>(n); // expected-error {{constant expression}} expected-note {{modification}}
-}
OpenPOWER on IntegriCloud