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]

[PATCH] Fix i386 -fPIC C++ ICE


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

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