summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/constant-expression-cxx11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp76
1 files changed, 10 insertions, 66 deletions
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 {
OpenPOWER on IntegriCloud