summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/except.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/except.c')
-rw-r--r--contrib/gcc/cp/except.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c
index f97ab06..66a3b16 100644
--- a/contrib/gcc/cp/except.c
+++ b/contrib/gcc/cp/except.c
@@ -709,12 +709,25 @@ build_throw (tree exp)
/* And initialize the exception object. */
if (CLASS_TYPE_P (temp_type))
{
+ int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+
+ /* 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. */
+ TREE_CODE (exp) == VAR_DECL
+ && DECL_CONTEXT (exp) == current_function_decl
+ && ! TREE_STATIC (exp)
+ /* The variable must not have the `volatile' qualifier. */
+ && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE))
+ flags = flags | LOOKUP_PREFER_RVALUE;
+
/* Call the copy constructor. */
exp = (build_special_member_call
(object, complete_ctor_identifier,
build_tree_list (NULL_TREE, exp),
TREE_TYPE (object),
- LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING));
+ flags));
if (exp == error_mark_node)
{
error (" in thrown expression");
OpenPOWER on IntegriCloud