OK.
On Tue, Sep 4, 2018 at 7:01 PM, Marek Polacek <pola...@redhat.com> wrote: > It occurred to me that we should be able to use treat_lvalue_as_rvalue_p in > the > second context where we're supposed to use a move operation as well. Except > that for a throw-expression, the operand may not be a function parameter. > While at it, also make use of CP_TYPE_VOLATILE_P. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2018-09-04 Marek Polacek <pola...@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. > > diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h > index 43e452cc1a3..df441fca304 100644 > --- gcc/cp/cp-tree.h > +++ gcc/cp/cp-tree.h > @@ -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); > diff --git gcc/cp/except.c gcc/cp/except.c > index f85ae047cfc..2db90eedcf7 100644 > --- gcc/cp/except.c > +++ gcc/cp/except.c > @@ -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); > diff --git gcc/cp/typeck.c gcc/cp/typeck.c > index ab088a946b3..84cf4c478aa 100644 > --- gcc/cp/typeck.c > +++ gcc/cp/typeck.c > @@ -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)) > {