]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix empty base stores in cxx_eval_store_expression [PR100111]
authorJakub Jelinek <jakub@redhat.com>
Fri, 16 Apr 2021 15:37:07 +0000 (17:37 +0200)
committerJakub Jelinek <jakub@redhat.com>
Fri, 16 Apr 2021 15:44:03 +0000 (17:44 +0200)
In r11-6895 handling of empty bases has been fixed such that non-lval
stores of empty classes are not added when the type of *valp doesn't
match the type of the initializer, but as this testcase shows it is
done only when *valp is non-NULL.  If it is NULL, we still shouldn't
add empty class constructors if the type of the constructor elt *valp
points to doesn't match.

2021-04-16  Jakub Jelinek  <jakub@redhat.com>

PR c++/100111
* constexpr.c (cxx_eval_store_expression): Don't add CONSTRUCTORs
for empty classes into *valp when types don't match even when *valp
is NULL.

* g++.dg/cpp0x/constexpr-100111.C: New test.

gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-100111.C [new file with mode: 0644]

index b74bbac3cd26b80393b3aa877edad1515f4d864f..0fb0ab44b39e3f0cf6bf6a3e01cdf3c80228f120 100644 (file)
@@ -5538,6 +5538,14 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
       CONSTRUCTOR_NO_CLEARING (*valp)
        = CONSTRUCTOR_NO_CLEARING (init);
     }
+  else if (TREE_CODE (init) == CONSTRUCTOR
+          && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init),
+                                                         type))
+    {
+      /* See above on initialization of empty bases.  */
+      gcc_assert (is_empty_class (TREE_TYPE (init)) && !lval);
+      return init;
+    }
   else
     *valp = init;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-100111.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-100111.C
new file mode 100644 (file)
index 0000000..446d21d
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/100111
+// { dg-do compile { target c++11 } }
+// { dg-options "-fno-elide-constructors" }
+
+struct A {};
+struct B : A { int b; constexpr B (A x) : A(x), b() {} };
+struct C { B c; constexpr C () : c({}) {} } d;