https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70590

--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Patrick Palka from comment #8)
> --- a/gcc/cp/constexpr.c
> +++ b/gcc/cp/constexpr.c
> @@ -4143,6 +4143,12 @@ cxx_eval_outermost_constant_expr (tree t, bool
> allow_non_constant,
>  
>    verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
>  
> +  /* Unshare the result unless it's a CONSTRUCTOR in which case it's already
> +     unshared.  */
> +  if (r != t
> +      && TREE_CODE (r) != CONSTRUCTOR)
> +    r = unshare_expr (r);
> +
>    /* Mutable logic is a bit tricky: we want to allow initialization of
>       constexpr variables with mutable members, but we can't copy those
>       members to another constexpr variable.  */

Wouldn't it be better to move it even further down, so that we don't unshare
even when actually not returning r or something based on it?
E.g. (completely untested)?

--- gcc/cp/constexpr.c.jj       2016-04-07 23:27:44.000000000 +0200
+++ gcc/cp/constexpr.c  2016-04-08 17:36:49.774326934 +0200
@@ -4168,6 +4168,11 @@ cxx_eval_outermost_constant_expr (tree t
     return error_mark_node;
   else if (non_constant_p && TREE_CONSTANT (r))
     {
+      /* Unshare the result unless it's a CONSTRUCTOR in which case it's
+         already unshared.  */
+      if (r != t && TREE_CODE (r) != CONSTRUCTOR)
+       r = unshare_expr (r);
+
       /* This isn't actually constant, so unset TREE_CONSTANT.  */
       if (EXPR_P (r))
        r = copy_node (r);
@@ -4179,6 +4184,10 @@ cxx_eval_outermost_constant_expr (tree t
     }
   else if (non_constant_p || r == t)
     return t;
+  /* Unshare the result unless it's a CONSTRUCTOR in which case it's
+     already unshared.  */
+  else if (r != t && TREE_CODE (r) != CONSTRUCTOR)
+    r = unshare_expr (r);

   if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
     {

Reply via email to