diff options
Diffstat (limited to 'clang/test/SemaCXX/constant-expression-cxx1y.cpp')
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx1y.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp index 07ef7974d11..fe69d105023 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -1159,3 +1159,49 @@ 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}} +} |