[PATCH] Fix i386 C++ ICE

Jakub Jelinek jakub@redhat.com
Mon Jun 12 05:52:00 GMT 2000


Hi!

Below is an attempt to fix the testcase below I've posted 5 days ago.
If we encounter duplicate typedef, we change the original typedef quite a
bit in duplicate_decls and kill DECL_ORIGINAL_TYPE at that time.
Later on, when duplicate_decls is called on the actual var_decl of the
foo::a, it does not work because it thinks in common_types original_type()'s
are different and promotes it in type_after_usual_arithmetic_conversions.
Bootstrap on i386-*-linux is still running.

2000-06-12  Jakub Jelinek  <jakub@redhat.com>

	* decl.c (pushdecl): Set DECL_ORIGINAL_TYPE of a duplicate TYPE_DECL
	again after calling duplicate_decls.

	* g++.old-deja/g++.other/type.C: New test.

--- gcc/testsuite/g++.old-deja/g++.other/type.C.jj	Wed Jun  7 13:11:28 2000
+++ gcc/testsuite/g++.old-deja/g++.other/type.C	Wed Jun  7 13:11:22 2000
@@ -0,0 +1,15 @@
+// Build don't link:
+
+typedef unsigned short ushort;
+class foo {
+public:
+  static ushort a;
+};
+extern "C" {
+typedef unsigned short ushort;
+}
+ushort foo::a;
+static int baz()
+{
+  return foo::a;
+}
--- gcc/cp/decl.c.jj	Mon Jun 12 09:55:42 2000
+++ gcc/cp/decl.c	Mon Jun 12 14:23:56 2000
@@ -3915,7 +3915,34 @@ pushdecl (x)
 	  else if (duplicate_decls (x, t))
 	    {
 	      if (TREE_CODE (t) == TYPE_DECL)
-		SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
+		{
+		  /* If declaring a type as a typedef, copy the type (unless
+		     we're at line 0), and install this TYPE_DECL as the new
+		     type's typedef name.  See the extensive comment in
+		     ../c-decl.c (pushdecl). */
+		  tree type = TREE_TYPE (t);
+		  if (DECL_ORIGINAL_TYPE (t) == NULL
+		      && DECL_SOURCE_LINE (t) != 0
+		      && type != error_mark_node && TYPE_NAME (type) != t
+		      /* We don't want to copy the type when all we're
+			 doing is making a TYPE_DECL for the purposes of
+			 inlining.  */
+		      && (!TYPE_NAME (type)
+			  || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (t)))
+		    {
+		      DECL_ORIGINAL_TYPE (t) = type;
+		      type = build_type_copy (type);
+		      TYPE_STUB_DECL (type) =
+			TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (t));
+		      TYPE_NAME (type) = t;
+		      TREE_TYPE (t) = type;
+		      if (TYPE_IDENTIFIER (type))
+			set_identifier_type_value_with_scope (DECL_NAME (t),
+						type, current_binding_level);
+		    }
+			      
+		  SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
+		}
 	      else if (TREE_CODE (t) == FUNCTION_DECL)
 		check_default_args (t);
 

	Jakub


More information about the Gcc-patches mailing list