cp-tree.h (treat_lvalue_as_rvalue_p): Declare.
authorMarek Polacek <polacek@redhat.com>
Wed, 5 Sep 2018 02:08:19 +0000 (02:08 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 5 Sep 2018 02:08:19 +0000 (02:08 +0000)
* cp-tree.h (treat_lvalue_as_rvalue_p): Declare.
* except.c (build_throw): Use it.  Use CP_TYPE_VOLATILE_P.
* typeck.c (treat_lvalue_as_rvalue_p): No longer static.  Add PARM_OK
parameter.
(maybe_warn_pessimizing_move): Adjust treat_lvalue_as_rvalue_p call.
(check_return_expr): Likewise.

From-SVN: r264101

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/cp/typeck.c

index 55d8290..3fbfe18 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-04  Marek Polacek  <polacek@redhat.com>
+
+       * cp-tree.h (treat_lvalue_as_rvalue_p): Declare.
+       * except.c (build_throw): Use it.  Use CP_TYPE_VOLATILE_P.
+       * typeck.c (treat_lvalue_as_rvalue_p): No longer static.  Add PARM_OK
+       parameter.
+       (maybe_warn_pessimizing_move): Adjust treat_lvalue_as_rvalue_p call.
+       (check_return_expr): Likewise.
+
 2018-09-03  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/84980
index 43e452c..df441fc 100644 (file)
@@ -7354,6 +7354,7 @@ extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 extern tree finish_left_unary_fold_expr      (tree, int);
 extern tree finish_right_unary_fold_expr     (tree, int);
 extern tree finish_binary_fold_expr          (tree, tree, int);
+extern bool treat_lvalue_as_rvalue_p        (tree, bool);
 
 /* in typeck2.c */
 extern void require_complete_eh_spec_types     (tree, tree);
index f85ae04..2db90ee 100644 (file)
@@ -676,12 +676,9 @@ build_throw (tree exp)
          /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
             treated as an rvalue for the purposes of overload resolution
             to favor move constructors over copy constructors.  */
-         if (/* Must be a local, automatic variable.  */
-             VAR_P (exp)
-             && DECL_CONTEXT (exp) == current_function_decl
-             && ! TREE_STATIC (exp)
+         if (treat_lvalue_as_rvalue_p (exp, /*parm_ok*/false)
              /* The variable must not have the `volatile' qualifier.  */
-             && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
+             && !CP_TYPE_VOLATILE_P (TREE_TYPE (exp)))
            {
              tree moved = move (exp);
              exp_vec = make_tree_vector_single (moved);
index ab088a9..84cf4c4 100644 (file)
@@ -9180,14 +9180,15 @@ can_do_nrvo_p (tree retval, tree functype)
 }
 
 /* Returns true if we should treat RETVAL, an expression being returned,
-   as if it were designated by an rvalue.  See [class.copy.elision].  */
+   as if it were designated by an rvalue.  See [class.copy.elision].
+   PARM_P is true if a function parameter is OK in this context.  */
 
-static bool
-treat_lvalue_as_rvalue_p (tree retval)
+bool
+treat_lvalue_as_rvalue_p (tree retval, bool parm_ok)
 {
   return ((cxx_dialect != cxx98)
          && ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval))
-             || TREE_CODE (retval) == PARM_DECL)
+             || (parm_ok && TREE_CODE (retval) == PARM_DECL))
          && DECL_CONTEXT (retval) == current_function_decl
          && !TREE_STATIC (retval));
 }
@@ -9240,7 +9241,7 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
            }
          /* Warn if the move is redundant.  It is redundant when we would
             do maybe-rvalue overload resolution even without std::move.  */
-         else if (treat_lvalue_as_rvalue_p (arg))
+         else if (treat_lvalue_as_rvalue_p (arg, /*parm_ok*/true))
            {
              auto_diagnostic_group d;
              if (warning_at (loc, OPT_Wredundant_move,
@@ -9525,7 +9526,7 @@ check_return_expr (tree retval, bool *no_warning)
          Note that these conditions are similar to, but not as strict as,
         the conditions for the named return value optimization.  */
       bool converted = false;
-      if (treat_lvalue_as_rvalue_p (retval)
+      if (treat_lvalue_as_rvalue_p (retval, /*parm_ok*/true)
          /* This is only interesting for class type.  */
          && CLASS_TYPE_P (functype))
        {