This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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*/);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]