Avoid taking the address of something just because it's in parens.
authorJason Merrill <jason@redhat.com>
Fri, 22 Jun 2018 21:57:01 +0000 (17:57 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 22 Jun 2018 21:57:01 +0000 (17:57 -0400)
* constexpr.c (same_type_ignoring_tlq_and_bounds_p): New.
(cxx_fold_indirect_ref): Use it.
(cxx_eval_constant_expression) [VIEW_CONVERT_EXPR]: Use it.
* cp-tree.h (REF_PARENTHESIZED_P): Allow VIEW_CONVERT_EXPR.
* semantics.c (force_paren_expr): Use VIEW_CONVERT_EXPR instead of
static_cast to reference type.
(maybe_undo_parenthesized_ref): Handle VIEW_CONVERT_EXPR.

From-SVN: r261971

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/cp-tree.h
gcc/cp/semantics.c

index f0e44532348224482d287c0e7eed75cca1b92b19..8c7b19b1754e41c4cbd03a513d06c405bc1a8ad8 100644 (file)
@@ -1,3 +1,14 @@
+2018-06-22  Jason Merrill  <jason@redhat.com>
+
+       Avoid taking the address of something just because it's in parens.
+       * constexpr.c (same_type_ignoring_tlq_and_bounds_p): New.
+       (cxx_fold_indirect_ref): Use it.
+       (cxx_eval_constant_expression) [VIEW_CONVERT_EXPR]: Use it.
+       * cp-tree.h (REF_PARENTHESIZED_P): Allow VIEW_CONVERT_EXPR.
+       * semantics.c (force_paren_expr): Use VIEW_CONVERT_EXPR instead of
+       static_cast to reference type.
+       (maybe_undo_parenthesized_ref): Handle VIEW_CONVERT_EXPR.
+
 2018-06-21  Jason Merrill  <jason@redhat.com>
 
        * pt.c (tsubst) [TEMPLATE_TYPE_PARM]: Use TEMPLATE_PARM_DESCENDANTS.
index 44f3093ab471e78c0d7838481edfd5b506db1c6d..dea2a4e57b3c55b6384cc6e15c311642df38be89 100644 (file)
@@ -3076,6 +3076,23 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
     return r;
 }
 
+/* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
+   where the desired type is an array of unknown bounds because the variable
+   has had its bounds deduced since the wrapping expression was created.  */
+
+static bool
+same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
+{
+  while (TREE_CODE (type1) == ARRAY_TYPE
+        && TREE_CODE (type2) == ARRAY_TYPE
+        && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
+    {
+      type1 = TREE_TYPE (type1);
+      type2 = TREE_TYPE (type2);
+    }
+  return same_type_ignoring_top_level_qualifiers_p (type1, type2);
+}
+
 /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
    match.  We want to be less strict for simple *& folding; if we have a
    non-const temporary that we access through a const pointer, that should
@@ -3108,15 +3125,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
       if (TREE_CODE (op) == CONST_DECL)
        return DECL_INITIAL (op);
       /* *&p => p;  make sure to handle *&"str"[cst] here.  */
-      if (same_type_ignoring_top_level_qualifiers_p (optype, type)
-         /* Also handle the case where the desired type is an array of unknown
-            bounds because the variable has had its bounds deduced since the
-            ADDR_EXPR was created.  */
-         || (TREE_CODE (type) == ARRAY_TYPE
-             && TREE_CODE (optype) == ARRAY_TYPE
-             && TYPE_DOMAIN (type) == NULL_TREE
-             && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (optype),
-                                                           TREE_TYPE (type))))
+      if (same_type_ignoring_tlq_and_bounds_p (optype, type))
        {
          tree fop = fold_read_from_constant_string (op);
          if (fop)
@@ -4676,7 +4685,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
             conversion.  */
          return fold (t);
 
-       if (tcode == UNARY_PLUS_EXPR)
+       /* Handle an array's bounds having been deduced after we built
+          the wrapping expression.  */
+       if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
+         r = op;
+       else if (tcode == UNARY_PLUS_EXPR)
          r = fold_convert (TREE_TYPE (t), op);
        else
          r = fold_build1 (tcode, type, op);
index 0994377e5d78531814e9d1326cb39be56468ceec..f16f00c40ded1fc07804527edbdbe37560d5c0e3 100644 (file)
@@ -399,7 +399,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
       TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
       FNDECL_USED_AUTO (in FUNCTION_DECL)
       DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
-      REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF)
+      REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF, SCOPE_REF, VIEW_CONVERT_EXPR)
       AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
       CONSTRUCTOR_MUTABLE_POISON (in CONSTRUCTOR)
       OVL_HIDDEN_P (in OVERLOAD)
@@ -3676,7 +3676,7 @@ struct GTY(()) lang_decl {
    of the time in C++14 mode.  */
 
 #define REF_PARENTHESIZED_P(NODE) \
-  TREE_LANG_FLAG_2 (TREE_CHECK3 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF))
+  TREE_LANG_FLAG_2 (TREE_CHECK4 ((NODE), COMPONENT_REF, INDIRECT_REF, SCOPE_REF, VIEW_CONVERT_EXPR))
 
 /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
    constructor call, rather than an ordinary function call.  */
index bad712ee6e8e021ce6666e2b987c847ea469348e..da75f30885f8c71af76e72557af54c8185285de4 100644 (file)
@@ -1720,23 +1720,10 @@ force_paren_expr (tree expr)
     REF_PARENTHESIZED_P (expr) = true;
   else if (processing_template_decl)
     expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
-  else if (VAR_P (expr) && DECL_HARD_REGISTER (expr))
-    /* We can't bind a hard register variable to a reference.  */;
   else
     {
-      cp_lvalue_kind kind = lvalue_kind (expr);
-      if ((kind & ~clk_class) != clk_none)
-       {
-         tree type = unlowered_expr_type (expr);
-         bool rval = !!(kind & clk_rvalueref);
-         type = cp_build_reference_type (type, rval);
-         /* This inhibits warnings in, eg, cxx_mark_addressable
-            (c++/60955).  */
-         warning_sentinel s (extra_warnings);
-         expr = build_static_cast (type, expr, tf_error);
-         if (expr != error_mark_node)
-           REF_PARENTHESIZED_P (expr) = true;
-       }
+      expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
+      REF_PARENTHESIZED_P (expr) = true;
     }
 
   return expr;
@@ -1765,6 +1752,9 @@ maybe_undo_parenthesized_ref (tree t)
     }
   else if (TREE_CODE (t) == PAREN_EXPR)
     t = TREE_OPERAND (t, 0);
+  else if (TREE_CODE (t) == VIEW_CONVERT_EXPR
+          && REF_PARENTHESIZED_P (t))
+    t = TREE_OPERAND (t, 0);
 
   return t;
 }