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: Fix PR 14083


This PR is a crash on a conditional-expression where one arm of the
conditional is a throw-expression and the other is an lvalue of class
type.  Fixed by calling force_rvalue to convert the lvalue to an
rvalue, since the result of the entire conditional is an rvalue in
that case.

Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2004-02-13  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14083
	* call.c (build_conditional_expr): Call force_rvalue on the
	non-void operand in the case that one result is a throw-expression
	and the other is not.

2004-02-13  Mark Mitchell  <mark@codesourcery.com>

	PR c++/14083
	* g++.dg/eh/cond2.C: New test.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.461
diff -c -5 -p -r1.461 call.c
*** cp/call.c	13 Feb 2004 07:19:16 -0000	1.461
--- cp/call.c	13 Feb 2004 20:09:24 -0000
*************** build_conditional_expr (tree arg1, tree 
*** 3177,3190 ****
  	   throw-expression (_except.throw_); the result is of the
  	   type of the other and is an rvalue.
  
  	 --Both the second and the third operands have type void; the
  	   result is of type void and is an rvalue.  */
!       if ((TREE_CODE (arg2) == THROW_EXPR)
! 	  ^ (TREE_CODE (arg3) == THROW_EXPR))
! 	result_type = ((TREE_CODE (arg2) == THROW_EXPR) 
! 		       ? arg3_type : arg2_type);
        else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
  	result_type = void_type_node;
        else
  	{
  	  error ("`%E' has type `void' and is not a throw-expression",
--- 3177,3200 ----
  	   throw-expression (_except.throw_); the result is of the
  	   type of the other and is an rvalue.
  
  	 --Both the second and the third operands have type void; the
  	   result is of type void and is an rvalue.  */
!       if (TREE_CODE (arg2) == THROW_EXPR 
! 	  && TREE_CODE (arg3) != THROW_EXPR)
! 	{
! 	  arg3 = force_rvalue (arg3);
! 	  arg3_type = TREE_TYPE (arg3);
! 	  result_type = arg3_type;
! 	}
!       else if (TREE_CODE (arg2) != THROW_EXPR 
! 	       && TREE_CODE (arg3) == THROW_EXPR)
! 	{
! 	  arg2 = force_rvalue (arg2);
! 	  arg2_type = TREE_TYPE (arg2);
! 	  result_type = arg2_type;
! 	}
        else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
  	result_type = void_type_node;
        else
  	{
  	  error ("`%E' has type `void' and is not a throw-expression",
Index: testsuite/g++.dg/eh/cond2.C
===================================================================
RCS file: testsuite/g++.dg/eh/cond2.C
diff -N testsuite/g++.dg/eh/cond2.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/eh/cond2.C	13 Feb 2004 20:09:24 -0000
***************
*** 0 ****
--- 1,19 ----
+ // PR c++/14083
+ 
+ struct A { 
+   A() throw() { } 
+   A(const A&) throw() { } 
+ }; 
+  
+ struct X { 
+   A a; 
+   X(); 
+   X& operator=(const X& __str); 
+ }; 
+  
+ bool operator==(const X& __lhs, const char* __rhs); 
+         
+ int main() { 
+   X x; 
+   x=="" ? x : throw 1; 
+ }


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