Hi! cxx_eval_store_expression has code to propagate no_zero_init from outer ctors to inner ctors, if the outer ctor is known to be zero initialized, the inner one should be as well.
As the following patch shows, when changing active union member there needs to be an exception, even if the whole containing aggregate was zero initialized before, if we change the union member and just initialize some portion of the new one, we can't assume the rest is initialized. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-02-25 Jakub Jelinek <ja...@redhat.com> PR c++/89481 * constexpr.c (cxx_eval_store_expression): When changing active union member, set no_zero_init. * g++.dg/cpp1y/constexpr-89481.C: New test. --- gcc/cp/constexpr.c.jj 2019-02-21 22:20:24.838100126 +0100 +++ gcc/cp/constexpr.c 2019-02-25 10:18:32.526462730 +0100 @@ -3860,6 +3860,7 @@ cxx_eval_store_expression (const constex } /* Changing active member. */ vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0); + no_zero_init = true; } for (idx = 0; --- gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C.jj 2019-02-25 10:27:39.188382381 +0100 +++ gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C 2019-02-25 10:27:12.957818089 +0100 @@ -0,0 +1,24 @@ +// PR c++/89481 +// { dg-do compile { target c++14 } } + +constexpr int +foo () +{ + union U { long long a; int b[2]; } u { 5LL }; + u.b[1] = 4; // { dg-error "change of the active member of a union from" "" { target c++17_down } } + return u.b[0]; +} + +constexpr int +bar () +{ + union U { long long a; int b[2]; } u { 5LL }; + u.b[1] = 4; // { dg-error "change of the active member of a union from" "" { target c++17_down } } + return u.b[1]; +} + +static_assert (foo () == 0, ""); // { dg-error "non-constant condition for static assertion" } + // { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 } + // { dg-error "accessing uninitialized array element" "" { target c++2a } .-2 } +static_assert (bar () == 4, ""); // { dg-error "non-constant condition for static assertion" "" { target c++17_down } } + // { dg-message "in 'constexpr' expansion of" "" { target c++17_down } .-1 } Jakub