diff mbox series

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

Message ID 20190225224526.GY7611@tucnak
State New
Headers show
Series [C++] Fix up constexpr changing of active union member (PR c++/89481) | expand

Commit Message

Jakub Jelinek Feb. 25, 2019, 10:45 p.m. UTC
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.


	Jakub

Comments

Jason Merrill Feb. 26, 2019, 2:29 p.m. UTC | #1
On 2/25/19 5:45 PM, Jakub Jelinek wrote:
> 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?

OK.

Jason
diff mbox series

Patch

--- 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 }