diff mbox

C++ PATCH for c++/54652 (ICE with repeated typedef/attribute)

Message ID 52E72F20.1050703@redhat.com
State New
Headers show

Commit Message

Jason Merrill Jan. 28, 2014, 4:16 a.m. UTC
Since duplicate_decls throws away the new decl before returning 1, we 
need to make sure that we don't have anything pointing to it.  In a 
TYPE_DECL, the type points back to the decl via TYPE_NAME, so we always 
need to choose the type from the olddecl.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.
diff mbox

Patch

commit 9dd7f9667b090b7e8c045eecb8b16db6930204eb
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jan 27 14:16:36 2014 -0500

    	PR c++/54652
    	* decl.c (duplicate_decls): Always use oldtype for TYPE_DECL.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7ebb05d..c93c783 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1926,9 +1926,9 @@  duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
       /* Merge the data types specified in the two decls.  */
       newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
 
-      /* If merge_types produces a non-typedef type, just use the old type.  */
-      if (TREE_CODE (newdecl) == TYPE_DECL
-	  && newtype == DECL_ORIGINAL_TYPE (newdecl))
+      /* For typedefs use the old type, as the new type's DECL_NAME points
+	 at newdecl, which will be ggc_freed.  */
+      if (TREE_CODE (newdecl) == TYPE_DECL)
 	newtype = oldtype;
 
       if (VAR_P (newdecl))
diff --git a/gcc/testsuite/g++.dg/ext/attrib48.C b/gcc/testsuite/g++.dg/ext/attrib48.C
new file mode 100644
index 0000000..19a9959
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib48.C
@@ -0,0 +1,6 @@ 
+// PR c++/54652
+
+typedef unsigned L __attribute__ ((aligned));
+typedef unsigned L __attribute__ ((aligned));
+
+L l;