]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.h (REF_PARENTHESIZED_P): New.
authorJason Merrill <jason@redhat.com>
Fri, 7 Mar 2014 20:00:20 +0000 (15:00 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 7 Mar 2014 20:00:20 +0000 (15:00 -0500)
* cp-tree.h (REF_PARENTHESIZED_P): New.
* semantics.c (force_paren_expr): Set it.
* pt.c (do_auto_deduction): Check it.
(tsubst) [COMPONENT_REF]: Copy it.
* typeck.c (maybe_warn_about_useless_cast): Don't strip dereference.

From-SVN: r208412

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/typeck.c

index 988c3bf264f7b7c1f4e43a58a57a286afd375a47..f617c622fc14679548a66b1c14d458243a0a2cfc 100644 (file)
@@ -1,5 +1,11 @@
 2014-03-07  Jason Merrill  <jason@redhat.com>
 
+       * cp-tree.h (REF_PARENTHESIZED_P): New.
+       * semantics.c (force_paren_expr): Set it.
+       * pt.c (do_auto_deduction): Check it.
+       (tsubst) [COMPONENT_REF]: Copy it.
+       * typeck.c (maybe_warn_about_useless_cast): Don't strip dereference.
+
        * decl.c (create_array_type_for_decl): Only warn about invalid
        C++1y VLA if flag_iso or warn_vla>0.
        (grokdeclarator): Likewise.
index 8ec7d6aea1d90626c3f2a1b6f66a09c357892ab9..45e4d8217460f02ac02a41dc9f37ceb318284757 100644 (file)
@@ -100,6 +100,7 @@ c-common.h, not after.
       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, SCOPE_REF)
    3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
       ICS_BAD_FLAG (in _CONV)
       FN_TRY_BLOCK_P (in TRY_BLOCK)
@@ -3031,6 +3032,12 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 #define PAREN_STRING_LITERAL_P(NODE) \
   TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))
 
+/* Indicates whether a COMPONENT_REF has been parenthesized.  Currently
+   only set some of the time in C++14 mode.  */
+
+#define REF_PARENTHESIZED_P(NODE) \
+  TREE_LANG_FLAG_2 (COMPONENT_REF_CHECK (NODE))
+
 /* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
    constructor call, rather than an ordinary function call.  */
 #define AGGR_INIT_VIA_CTOR_P(NODE) \
index 6476d8aae56ef393e07ebf6d02bab387ad0e3376..d4d54b8984d858bd9079e06e891f539839d9919b 100644 (file)
@@ -14915,6 +14915,7 @@ tsubst_copy_and_build (tree t,
        tree object;
        tree object_type;
        tree member;
+       tree r;
 
        object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
                                                     args, complain, in_decl);
@@ -14999,11 +15000,19 @@ tsubst_copy_and_build (tree t,
            RETURN (error_mark_node);
          }
        else if (TREE_CODE (member) == FIELD_DECL)
-         RETURN (finish_non_static_data_member (member, object, NULL_TREE));
+         {
+           r = finish_non_static_data_member (member, object, NULL_TREE);
+           if (TREE_CODE (r) == COMPONENT_REF)
+             REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+           RETURN (r);
+         }
 
-       RETURN (finish_class_member_access_expr (object, member,
-                                               /*template_p=*/false,
-                                               complain));
+       r = finish_class_member_access_expr (object, member,
+                                            /*template_p=*/false,
+                                            complain);
+       if (TREE_CODE (r) == COMPONENT_REF)
+         REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
+       RETURN (r);
       }
 
     case THROW_EXPR:
@@ -21619,7 +21628,8 @@ do_auto_deduction (tree type, tree init, tree auto_node)
   targs = make_tree_vec (1);
   if (AUTO_IS_DECLTYPE (auto_node))
     {
-      bool id = (DECL_P (init) || TREE_CODE (init) == COMPONENT_REF);
+      bool id = (DECL_P (init) || (TREE_CODE (init) == COMPONENT_REF
+                                  && !REF_PARENTHESIZED_P (init)));
       TREE_VEC_ELT (targs, 0)
        = finish_decltype_type (init, id, tf_warning_or_error);
       if (type != auto_node)
index b9c1271e3898ba0067859f5a252df4faea613477..fcd840956572b403e643fb4f057d2bc8abb31dfa 100644 (file)
@@ -1605,11 +1605,18 @@ force_paren_expr (tree expr)
   if (cxx_dialect < cxx1y)
     return expr;
 
+  /* If we're in unevaluated context, we can't be deducing a
+     return/initializer type, so we don't need to mess with this.  */
+  if (cp_unevaluated_operand)
+    return expr;
+
   if (!DECL_P (expr) && TREE_CODE (expr) != COMPONENT_REF
       && TREE_CODE (expr) != SCOPE_REF)
     return expr;
 
-  if (type_dependent_expression_p (expr))
+  if (TREE_CODE (expr) == COMPONENT_REF)
+    REF_PARENTHESIZED_P (expr) = true;
+  else if (type_dependent_expression_p (expr))
     expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
   else
     {
@@ -1619,7 +1626,7 @@ force_paren_expr (tree expr)
          tree type = unlowered_expr_type (expr);
          bool rval = !!(kind & clk_rvalueref);
          type = cp_build_reference_type (type, rval);
-         expr = build_static_cast (type, expr, tf_warning_or_error);
+         expr = build_static_cast (type, expr, tf_error);
        }
     }
 
index c91612c767548e2cd2d313bd0a3426b1900265b3..d8374d9b0b4efb7194368abcc1e56aef7eae2198 100644 (file)
@@ -6291,7 +6291,10 @@ maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
   if (warn_useless_cast
       && complain & tf_warning)
     {
-      if (REFERENCE_REF_P (expr))
+      /* In C++14 mode, this interacts badly with force_paren_expr.  And it
+        isn't necessary in any mode, because the code below handles
+        glvalues properly.  For 4.9, just skip it in C++14 mode.  */
+      if (cxx_dialect < cxx1y && REFERENCE_REF_P (expr))
        expr = TREE_OPERAND (expr, 0);
 
       if ((TREE_CODE (type) == REFERENCE_TYPE