This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to build_conditional_expr for c++/10245
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 28 Mar 2003 19:37:33 -0500
- Subject: C++ PATCH to build_conditional_expr for c++/10245
We used to check real_lvalue_p, which was wrong because it allowed through
things like COMPONENT_REFs. In a previous patch, I stripped that test
entirely, so that we'd always ask for a new temporary. But in this case,
if we already have a temporary that's good enough; we don't need to
simulate another copy. All other uses of CONV_FORCE_TEMP are for
initializations, where we do need to check that the copy ctor is usable.
So I've split out the code for forcing an rvalue into a separate function,
which now just checks for TARGET_EXPR. This should work better.
Test in g++.dg/conversion/cond2.C. Tested i686-pc-linux-gnu, applied to
3.3 and trunk.
2003-03-28 Jason Merrill <jason at redhat dot com>
PR c++/10245
* cvt.c (force_rvalue): New fn.
* call.c (build_conditional_expr): Use it.
* cp-tree.h: Declare it.
*** cvt.c.~1~ 2003-03-28 17:26:24.000000000 -0500
--- cvt.c 2003-03-28 17:14:33.000000000 -0500
*************** convert_lvalue (tree totype, tree expr)
*** 573,578 ****
--- 573,593 ----
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. */
*** call.c.~1~ 2003-03-28 17:26:24.000000000 -0500
--- call.c 2003-03-28 17:14:45.000000000 -0500
*************** build_conditional_expr (tree arg1, tree
*** 3418,3435 ****
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_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_type = TREE_TYPE (arg3);
if (arg2 == error_mark_node || arg3 == error_mark_node)
--- 3418,3427 ----
We use ocp_convert rather than build_user_type_conversion because the
latter returns NULL_TREE on failure, while the former gives an error. */
! arg2 = force_rvalue (arg2);
arg2_type = TREE_TYPE (arg2);
! arg3 = force_rvalue (arg3);
arg3_type = TREE_TYPE (arg3);
if (arg2 == error_mark_node || arg3 == error_mark_node)
*** cp-tree.h.~1~ 2003-03-28 17:26:24.000000000 -0500
--- cp-tree.h 2003-03-28 17:16:17.000000000 -0500
*************** extern tree get_primary_binfo
*** 3646,3651 ****
--- 3646,3652 ----
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*/);