This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix i386 -fPIC C++ ICE
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] Fix i386 -fPIC C++ ICE
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Mon, 19 Jun 2000 12:37:51 +0200
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
Hi!
The testcase below causes an ICE in copy_to_mode_reg on i386 with -fPIC (no
matter what -O is given). The issue is that finish_switch_cond builds a
CLEANUP_POINT_EXPR, which has 32bit type, but inside of that
CLEANUP_POINT_EXPR sits an 8bit type and copy_to_mode_reg fails to copy from
a QImode to SImode directly.
I believe CLEANUP_POINT_EXPR's type should be the same as of the enclosed
expression and that's what this patch does.
Ok to commit? bootstrap/testsuite on i386-redhat-linux pending.
2000-06-19 Jakub Jelinek <jakub@redhat.com>
* semantics.c (finish_switch_cond): Use the actual type of cond to
build CLEANUP_POINT_EXPR.
* g++.old-deja/g++.other/case.C: New test.
--- gcc/cp/semantics.c.jj Mon Jun 19 11:17:47 2000
+++ gcc/cp/semantics.c Mon Jun 19 11:57:37 2000
@@ -612,10 +612,8 @@ finish_switch_cond (cond, switch_stmt)
if (cond != error_mark_node)
{
tree idx;
- tree type;
cond = default_conversion (cond);
- type = TREE_TYPE (cond);
idx = get_unwidened (cond, 0);
/* We can't strip a conversion from a signed type to an unsigned,
because if we did, int_fits_type_p would do the wrong thing
@@ -625,7 +623,7 @@ finish_switch_cond (cond, switch_stmt)
== TREE_UNSIGNED (TREE_TYPE (idx)))
cond = idx;
- cond = fold (build1 (CLEANUP_POINT_EXPR, type, cond));
+ cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond));
}
}
FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
--- gcc/testsuite/g++.old-deja/g++.other/case.C.jj Mon Jun 19 12:02:40 2000
+++ gcc/testsuite/g++.old-deja/g++.other/case.C Mon Jun 19 12:04:48 2000
@@ -0,0 +1,27 @@
+// Build don't link:
+// Special g++ Options: -fPIC
+// Origin: Jakub Jelinek <jakub@redhat.com>
+
+class foo {
+public:
+ char a();
+};
+class bar {
+public:
+ void b();
+ foo c();
+};
+void baz(bar rst)
+{
+ switch (rst.c().a())
+ {
+ case 1:
+ rst.b(); break;
+ case 2:
+ rst.b(); break;
+ case 3:
+ rst.b(); break;
+ case 4:
+ rst.b(); break;
+ }
+}
Jakub