aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/except.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/except.c')
-rw-r--r--gcc/cp/except.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index aca54f1..cb1a410 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -696,21 +696,25 @@ build_throw (location_t loc, 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 (treat_lvalue_as_rvalue_p (exp, /*parm_ok*/false)
- /* The variable must not have the `volatile' qualifier. */
- && !CP_TYPE_VOLATILE_P (TREE_TYPE (exp)))
+ if (tree moved = treat_lvalue_as_rvalue_p (exp, /*return*/false))
{
- tree moved = move (exp);
- releasing_vec exp_vec (make_tree_vector_single (moved));
- moved = (build_special_member_call
- (object, complete_ctor_identifier, &exp_vec,
- TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE,
- tf_none));
- if (moved != error_mark_node)
+ if (cxx_dialect < cxx20)
{
- exp = moved;
- converted = true;
+ releasing_vec exp_vec (make_tree_vector_single (moved));
+ moved = (build_special_member_call
+ (object, complete_ctor_identifier, &exp_vec,
+ TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE,
+ tf_none));
+ if (moved != error_mark_node)
+ {
+ exp = moved;
+ converted = true;
+ }
}
+ else
+ /* In C++20 we just treat the return value as an rvalue that
+ can bind to lvalue refs. */
+ exp = moved;
}
/* Call the copy constructor. */