]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix various latent issues revealed by P0732 work.
authorJason Merrill <jason@redhat.com>
Mon, 5 Nov 2018 07:46:57 +0000 (02:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 5 Nov 2018 07:46:57 +0000 (02:46 -0500)
The initialized_type hunk fixes handling of void AGGR_INIT_EXPRs that call a
non-constructor; an AGGR_INIT_EXPR can have void type if its initialization
semantics are more complicated than just expanding the call.

The cxx_eval_vec_init_1 hunk corrects AGGR_INIT_EXPRs that were
nonsensically built to initialize an object of void type.  And the
build_aggr_init_expr hunk makes sure we don't do that again.

The ocp_convert and cxx_eval_outermost_constant_expr hunks deal with making
sure that a constant CONSTRUCTOR has the right type.

* cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR.
* constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling.
(cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR.
(cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the
right type.  Don't wrap a CONSTRUCTOR if one was passed in.
* tree.c (build_aggr_init_expr): Check for void.

From-SVN: r265788

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/cvt.c
gcc/cp/tree.c

index 7e9c0e2642ae3f4d172e81719e677583463b74ab..4f40627a2261fc456f53411d38171ed5ec97fa81 100644 (file)
@@ -1,5 +1,12 @@
 2018-11-04  Jason Merrill  <jason@redhat.com>
 
+       * cvt.c (ocp_convert): Don't wrap a CONSTRUCTOR in a NOP_EXPR.
+       * constexpr.c (initialized_type): Fix AGGR_INIT_EXPR handling.
+       (cxx_eval_vec_init_1): Correct type of AGGR_INIT_EXPR.
+       (cxx_eval_outermost_constant_expr): Make sure a CONSTRUCTOR has the
+       right type.  Don't wrap a CONSTRUCTOR if one was passed in.
+       * tree.c (build_aggr_init_expr): Check for void.
+
        PR c++/60503 - wrong lambda attribute syntax.
        * parser.c (cp_parser_lambda_declarator_opt): Fix attribute
        handling.
index 7692b1727da0219fa9f19db714bd4f0f6a114254..4fb1ba527e3207149e1703f1477d4060bf4bcc51 100644 (file)
@@ -2778,8 +2778,10 @@ initialized_type (tree t)
 {
   if (TYPE_P (t))
     return t;
-  tree type = cv_unqualified (TREE_TYPE (t));
-  if (TREE_CODE (t) == CALL_EXPR || TREE_CODE (t) == AGGR_INIT_EXPR)
+  tree type = TREE_TYPE (t);
+  if (!VOID_TYPE_P (type))
+    /* No need to look deeper.  */;
+  else if (TREE_CODE (t) == CALL_EXPR)
     {
       /* A constructor call has void type, so we need to look deeper.  */
       tree fn = get_function_named_in_call (t);
@@ -2787,7 +2789,9 @@ initialized_type (tree t)
          && DECL_CXX_CONSTRUCTOR_P (fn))
        type = DECL_CONTEXT (fn);
     }
-  return type;
+  else if (TREE_CODE (t) == AGGR_INIT_EXPR)
+    type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
+  return cv_unqualified (type);
 }
 
 /* We're about to initialize element INDEX of an array or class from VALUE.
@@ -3000,7 +3004,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
                                        &argvec, elttype, LOOKUP_NORMAL,
                                        complain);
       release_tree_vector (argvec);
-      init = build_aggr_init_expr (TREE_TYPE (init), init);
+      init = build_aggr_init_expr (elttype, init);
       pre_init = true;
     }
 
@@ -5089,7 +5093,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
        r = build_nop (TREE_TYPE (r), r);
       TREE_CONSTANT (r) = false;
     }
-  else if (non_constant_p || r == t)
+  else if (non_constant_p)
     return t;
 
   if (should_unshare)
@@ -5097,18 +5101,18 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
 
   if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
     {
+      r = adjust_temp_type (type, r);
       if (TREE_CODE (t) == TARGET_EXPR
          && TARGET_EXPR_INITIAL (t) == r)
        return t;
-      else
+      else if (TREE_CODE (t) != CONSTRUCTOR)
        {
          r = get_target_expr (r);
          TREE_CONSTANT (r) = true;
-         return r;
        }
     }
-  else
-    return r;
+
+  return r;
 }
 
 /* Returns true if T is a valid subexpression of a constant expression,
index 315b0d6a65acbeb2455478ca42e9cfae70d0089a..b04e9a70652663010433513f560339319713a480 100644 (file)
@@ -725,7 +725,8 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
     /* We need a new temporary; don't take this shortcut.  */;
   else if (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (e)))
     {
-      if (same_type_p (type, TREE_TYPE (e)))
+      tree etype = TREE_TYPE (e);
+      if (same_type_p (type, etype))
        /* The call to fold will not always remove the NOP_EXPR as
           might be expected, since if one of the types is a typedef;
           the comparison in fold is just equality of pointers, not a
@@ -743,9 +744,16 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
        {
          /* Don't build a NOP_EXPR of class type.  Instead, change the
             type of the temporary.  */
+         gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
          TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
          return e;
        }
+      else if (TREE_CODE (e) == CONSTRUCTOR)
+       {
+         gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, etype));
+         TREE_TYPE (e) = type;
+         return e;
+       }
       else
        {
          /* We shouldn't be treating objects of ADDRESSABLE type as
index 74018e97bb76c90806c524209bb3b2476308f3b2..51af9f2015e2c2a5bce144dc63fe6b9c48fac750 100644 (file)
@@ -576,6 +576,8 @@ build_aggr_init_expr (tree type, tree init)
   tree rval;
   int is_ctor;
 
+  gcc_assert (!VOID_TYPE_P (type));
+
   /* Don't build AGGR_INIT_EXPR in a template.  */
   if (processing_template_decl)
     return init;