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

Reply via email to