From f7b9026e22187c0467cfbb7822790ed81ec8b46c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 28 Mar 2003 19:49:34 -0500 Subject: [PATCH] re PR c++/10245 (?: operator requires public copy constructor of return type) PR c++/10245 * cvt.c (force_rvalue): New fn. * call.c (build_conditional_expr): Use it. * cp-tree.h: Declare it. From-SVN: r65005 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/call.c | 12 ++---------- gcc/cp/cp-tree.h | 1 + gcc/cp/cvt.c | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2dc2bb7a2a9..dcaf0e4a0a2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2003-03-28 Jason Merrill + + PR c++/10245 + * cvt.c (force_rvalue): New fn. + * call.c (build_conditional_expr): Use it. + * cp-tree.h: Declare it. + 2003-03-28 Mike Stump * error.c (dump_expr): Add 0x to printed hex numbers to make diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 101b3417435..b2f9291139f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3418,18 +3418,10 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) We use ocp_convert rather than build_user_type_conversion because the latter returns NULL_TREE on failure, while the former gives an error. */ - if (IS_AGGR_TYPE (TREE_TYPE (arg2))) - arg2 = ocp_convert (TREE_TYPE (arg2), arg2, - CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); - else - arg2 = decay_conversion (arg2); + arg2 = force_rvalue (arg2); arg2_type = TREE_TYPE (arg2); - if (IS_AGGR_TYPE (TREE_TYPE (arg3))) - arg3 = ocp_convert (TREE_TYPE (arg3), arg3, - CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); - else - arg3 = decay_conversion (arg3); + arg3 = force_rvalue (arg3); arg3_type = TREE_TYPE (arg3); if (arg2 == error_mark_node || arg3 == error_mark_node) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 82fc020e630..f4d9ab9c023 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3647,6 +3647,7 @@ extern tree get_primary_binfo (tree); extern tree convert_to_reference (tree, tree, int, int, tree); extern tree convert_from_reference (tree); extern tree convert_lvalue (tree, tree); +extern tree force_rvalue (tree); extern tree ocp_convert (tree, tree, int, int); extern tree cp_convert (tree, tree); extern tree convert_to_void (tree, const char */*implicit context*/); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 88e802e14b0..19bca82f076 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -573,6 +573,21 @@ convert_lvalue (tree totype, tree expr) NULL_TREE); return convert_from_reference (expr); } + +/* Really perform an lvalue-to-rvalue conversion, including copying an + argument of class type into a temporary. */ + +tree +force_rvalue (tree expr) +{ + if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR) + expr = ocp_convert (TREE_TYPE (expr), expr, + CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL); + else + expr = decay_conversion (expr); + + return expr; +} /* C++ conversions, preference to static cast conversions. */ -- 2.30.2