This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix PR 14083
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 13 Feb 2004 12:13:28 -0800
- Subject: C++ PATCH: Fix PR 14083
- Reply-to: mark at codesourcery dot com
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;
+ }