aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-02-10 13:50:30 -0500
committerJason Merrill <jason@gcc.gnu.org>2017-02-10 13:50:30 -0500
commit5c97093ba7feef2235c45233a2a1175c8c168b4c (patch)
treeca9ee3b791d659df5e956f947849e73bb4d09560
parentf494ac0ebd96a964914b7d9cc7b208a69865f9f1 (diff)
downloadgcc-5c97093ba7feef2235c45233a2a1175c8c168b4c.zip
gcc-5c97093ba7feef2235c45233a2a1175c8c168b4c.tar.gz
gcc-5c97093ba7feef2235c45233a2a1175c8c168b4c.tar.bz2
PR c++/78897 - constexpr union
* constexpr.c (cxx_eval_store_expression): A store to a union member erases a previous store to another member. From-SVN: r245341
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/constexpr.c5
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-union1.C11
3 files changed, 20 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 68c5d9d..be51428 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2017-02-10 Jason Merrill <jason@redhat.com>
+ PR c++/78897 - constexpr union
+ * constexpr.c (cxx_eval_store_expression): A store to a union member
+ erases a previous store to another member.
+
PR c++/71285 - member of fold-expression
* semantics.c (finish_unary_fold_expr)
(finish_binary_fold_expr): Use null type for fold-expressions.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index bb45f1e..bfdde9e 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3466,6 +3466,11 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
unsigned HOST_WIDE_INT idx;
+ if (code == UNION_TYPE && CONSTRUCTOR_NELTS (*valp)
+ && CONSTRUCTOR_ELT (*valp, 0)->index != index)
+ /* Changing active member. */
+ vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
+
for (idx = 0;
vec_safe_iterate (CONSTRUCTOR_ELTS (*valp), idx, &cep);
idx++, fields = DECL_CHAIN (fields))
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-union1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-union1.C
new file mode 100644
index 0000000..8aed6d9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-union1.C
@@ -0,0 +1,11 @@
+// PR c++/78897
+// { dg-do compile { target c++14 } }
+
+struct Optional {
+ constexpr Optional() : _dummy{} { _value = 1; }
+ union {
+ int _dummy;
+ int _value;
+ };
+};
+Optional opt{};