aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-02-13 20:11:35 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-02-13 20:11:35 +0000
commit41dffe622d75043716fa6aaea7bba387751d7441 (patch)
tree0203969aadadf5624994ab772a5d5415a8c1d75f /gcc
parent1daa84b6e2fee1548afaabb0d99fc797f1aa0f1c (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/eh/cond2.C19
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;
+}