[C++ PATCH] Fix up constexpr changing of active union member (PR c++/89481)

Jakub Jelinek jakub@redhat.com
Mon Feb 25 22:56:00 GMT 2019


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  <jakub@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



More information about the Gcc-patches mailing list