We don't unshare CONSTRUCTORs as often during constexpr evaluation, so we
need to unshare them here.
* constexpr.c (cxx_eval_outermost_constant_expr): Don't assume
CONSTRUCTORs are already unshared.
From-SVN: r280127
2020-01-10 Jason Merrill <jason@redhat.com>
+ PR c++/93143 - incorrect tree sharing with constexpr.
+ * constexpr.c (cxx_eval_outermost_constant_expr): Don't assume
+ CONSTRUCTORs are already unshared.
+
PR c++/93173 - incorrect tree sharing.
PR c++/93033
* cp-gimplify.c (cp_gimplify_init_expr, cp_gimplify_expr): Use
if (!non_constant_p && overflow_p)
non_constant_p = true;
- /* Unshare the result unless it's a CONSTRUCTOR in which case it's already
- unshared. */
+ /* Unshare the result. */
bool should_unshare = true;
- if (r == t || TREE_CODE (r) == CONSTRUCTOR)
+ if (r == t || (TREE_CODE (t) == TARGET_EXPR
+ && TARGET_EXPR_INITIAL (t) == r))
should_unshare = false;
if (non_constant_p && !allow_non_constant)
--- /dev/null
+// PR c++/93143
+// { dg-do run { target c++11 } }
+
+struct A { char a[2]; };
+
+static constexpr A foo () { return A{1}; }
+
+void bar ()
+{
+ A a = foo ();
+ if (a.a[0] != 1)
+ __builtin_abort();
+}
+
+void foobar ()
+{
+ A x[] = { foo (), foo () };
+ A a = foo ();
+ if (a.a[0] != 1)
+ __builtin_abort();
+}
+
+int main()
+{
+ bar();
+ foobar();
+}