diff options
Diffstat (limited to 'clang/test/SemaCXX/constant-expression-cxx11.cpp')
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 76 |
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 { |