Commit 74be6f51 by Marek Polacek Committed by Marek Polacek

cp-tree.h (treat_lvalue_as_rvalue_p): Declare.

	* 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
parent fd64b293
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> 2018-09-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84980 PR c++/84980
......
...@@ -7354,6 +7354,7 @@ extern tree cp_perform_integral_promotions (tree, tsubst_flags_t); ...@@ -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_left_unary_fold_expr (tree, int);
extern tree finish_right_unary_fold_expr (tree, int); extern tree finish_right_unary_fold_expr (tree, int);
extern tree finish_binary_fold_expr (tree, tree, int); extern tree finish_binary_fold_expr (tree, tree, int);
extern bool treat_lvalue_as_rvalue_p (tree, bool);
/* in typeck2.c */ /* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree); extern void require_complete_eh_spec_types (tree, tree);
......
...@@ -676,12 +676,9 @@ build_throw (tree exp) ...@@ -676,12 +676,9 @@ build_throw (tree exp)
/* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
treated as an rvalue for the purposes of overload resolution treated as an rvalue for the purposes of overload resolution
to favor move constructors over copy constructors. */ to favor move constructors over copy constructors. */
if (/* Must be a local, automatic variable. */ if (treat_lvalue_as_rvalue_p (exp, /*parm_ok*/false)
VAR_P (exp)
&& DECL_CONTEXT (exp) == current_function_decl
&& ! TREE_STATIC (exp)
/* The variable must not have the `volatile' qualifier. */ /* 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); tree moved = move (exp);
exp_vec = make_tree_vector_single (moved); exp_vec = make_tree_vector_single (moved);
......
...@@ -9180,14 +9180,15 @@ can_do_nrvo_p (tree retval, tree functype) ...@@ -9180,14 +9180,15 @@ can_do_nrvo_p (tree retval, tree functype)
} }
/* Returns true if we should treat RETVAL, an expression being returned, /* 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 bool
treat_lvalue_as_rvalue_p (tree retval) treat_lvalue_as_rvalue_p (tree retval, bool parm_ok)
{ {
return ((cxx_dialect != cxx98) return ((cxx_dialect != cxx98)
&& ((VAR_P (retval) && !DECL_HAS_VALUE_EXPR_P (retval)) && ((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 && DECL_CONTEXT (retval) == current_function_decl
&& !TREE_STATIC (retval)); && !TREE_STATIC (retval));
} }
...@@ -9240,7 +9241,7 @@ maybe_warn_pessimizing_move (tree retval, tree functype) ...@@ -9240,7 +9241,7 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
} }
/* Warn if the move is redundant. It is redundant when we would /* Warn if the move is redundant. It is redundant when we would
do maybe-rvalue overload resolution even without std::move. */ 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; auto_diagnostic_group d;
if (warning_at (loc, OPT_Wredundant_move, if (warning_at (loc, OPT_Wredundant_move,
...@@ -9525,7 +9526,7 @@ check_return_expr (tree retval, bool *no_warning) ...@@ -9525,7 +9526,7 @@ check_return_expr (tree retval, bool *no_warning)
Note that these conditions are similar to, but not as strict as, Note that these conditions are similar to, but not as strict as,
the conditions for the named return value optimization. */ the conditions for the named return value optimization. */
bool converted = false; 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. */ /* This is only interesting for class type. */
&& CLASS_TYPE_P (functype)) && CLASS_TYPE_P (functype))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment