diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-02-13 20:11:35 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-02-13 20:11:35 +0000 |
commit | 41dffe622d75043716fa6aaea7bba387751d7441 (patch) | |
tree | 0203969aadadf5624994ab772a5d5415a8c1d75f | |
parent | 1daa84b6e2fee1548afaabb0d99fc797f1aa0f1c (diff) | |
download | gcc-41dffe622d75043716fa6aaea7bba387751d7441.zip gcc-41dffe622d75043716fa6aaea7bba387751d7441.tar.gz gcc-41dffe622d75043716fa6aaea7bba387751d7441.tar.bz2 |
re PR c++/14083 (ICE in conditional expression operator with throw)
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.
PR c++/14083
* g++.dg/eh/cond2.C: New test.
From-SVN: r77768
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/cond2.C | 19 |
4 files changed, 45 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4238dea..89d8edc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +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 Ian Lance Taylor <ian@wasabisystems.com> PR c++/9851 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0f7c9e5..ba3b228 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3179,10 +3179,20 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) --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); + 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc197d4..dd13664 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-02-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/14083 + * g++.dg/eh/cond2.C: New test. + 2004-02-12 Alan Modra <amodra@bigpond.net.au> * gcc.dg/debug/20020327-1.c: Disable for powerpc64. diff --git a/gcc/testsuite/g++.dg/eh/cond2.C b/gcc/testsuite/g++.dg/eh/cond2.C new file mode 100644 index 0000000..e4b45f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/cond2.C @@ -0,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; +} |