re PR c++/33620 (internal compiler error: canonical types differ for identical types...
authorJason Merrill <jason@redhat.com>
Mon, 22 Oct 2007 18:03:10 +0000 (14:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 22 Oct 2007 18:03:10 +0000 (14:03 -0400)
        PR c++/33620
        * class.c (finish_struct_bits): Copy TYPE_ATTRIBUTES.
        * pt.c (apply_late_template_attributes): Splice out dependent
        attributes from DECL_ATTRIBUTES.

        * decl.c (cxx_maybe_build_cleanup): Use build_address.

From-SVN: r129553

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/ext/tmplattr7.C [new file with mode: 0644]

index 4283a88e249fed76d16d6c6bde6c908b0ff94466..903db53a3233714600247ad9112b02af3fc0b9d0 100644 (file)
@@ -1,3 +1,12 @@
+2007-10-22  Jason Merrill  <jason@redhat.com>
+
+       PR c++/33620
+       * class.c (finish_struct_bits): Copy TYPE_ATTRIBUTES.
+       * pt.c (apply_late_template_attributes): Splice out dependent
+       attributes from DECL_ATTRIBUTES.
+
+       * decl.c (cxx_maybe_build_cleanup): Use build_address.
+
 2007-10-17  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        * typeck.c (build_binary_op) : Use appropriate warning option
index 4419813b6b6847c170124f9a7b9455fa32851ffa..54dc14c17ef53cd33c00f2784aa32581492e6e23 100644 (file)
@@ -1452,6 +1452,9 @@ finish_struct_bits (tree t)
       TYPE_VFIELD (variants) = TYPE_VFIELD (t);
       TYPE_METHODS (variants) = TYPE_METHODS (t);
       TYPE_FIELDS (variants) = TYPE_FIELDS (t);
+
+      /* All variants of a class have the same attributes.  */
+      TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
     }
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
index 0a42b69ff4f6785fa6dc4d2290afa9fa58c93c94..136c8dfd1ac81d1e281e0430a21dd58e81128371 100644 (file)
@@ -12134,10 +12134,7 @@ cxx_maybe_build_cleanup (tree decl)
       if (TREE_CODE (type) == ARRAY_TYPE)
        addr = decl;
       else
-       {
-         cxx_mark_addressable (decl);
-         addr = build_unary_op (ADDR_EXPR, decl, 0);
-       }
+       addr = build_address (decl);
 
       /* Optimize for space over speed here.  */
       if (!has_vbases || flag_expensive_optimizations)
index 773c1041762e15b594706ba2abb69434c6e0d303..a54e90d6fa723bfb9ca9b8bf956146f3e6ce1717 100644 (file)
@@ -6488,23 +6488,47 @@ static void
 apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
                                tree args, tsubst_flags_t complain, tree in_decl)
 {
-  tree late_attrs = NULL_TREE;
+  tree last_dep = NULL_TREE;
   tree t;
+  tree *p;
+
+  for (t = attributes; t; t = TREE_CHAIN (t))
+    if (ATTR_IS_DEPENDENT (t))
+      {
+       last_dep = t;
+       attributes = copy_list (attributes);
+       break;
+      }
 
   if (DECL_P (*decl_p))
-    DECL_ATTRIBUTES (*decl_p) = attributes;
+    p = &DECL_ATTRIBUTES (*decl_p);
   else
-    TYPE_ATTRIBUTES (*decl_p) = attributes;
+    p = &TYPE_ATTRIBUTES (*decl_p);
 
-  for (t = attributes; t; t = TREE_CHAIN (t))
-    if (ATTR_IS_DEPENDENT (t))
-      late_attrs = tree_cons
-       (TREE_PURPOSE (t),
-        tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
-                     /*integral_constant_expression_p=*/false),
-        late_attrs);
+  if (last_dep)
+    {
+      tree late_attrs = NULL_TREE;
+      tree *q = &late_attrs;
 
-  cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+      for (*p = attributes; *p; )
+       {
+         t = *p;
+         if (ATTR_IS_DEPENDENT (t))
+           {
+             *p = TREE_CHAIN (t);
+             TREE_CHAIN (t) = NULL_TREE;
+             TREE_VALUE (t)
+               = tsubst_expr (TREE_VALUE (t), args, complain, in_decl,
+                              /*integral_constant_expression_p=*/false);
+             *q = t;
+             q = &TREE_CHAIN (t);
+           }
+         else
+           p = &TREE_CHAIN (t);
+       }
+
+      cplus_decl_attributes (decl_p, late_attrs, attr_flags);
+    }
 }
 
 tree
diff --git a/gcc/testsuite/g++.dg/ext/tmplattr7.C b/gcc/testsuite/g++.dg/ext/tmplattr7.C
new file mode 100644 (file)
index 0000000..ee6c418
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/33620
+
+template <typename T>
+struct __attribute__((visibility("default"))) List {};
+
+int bar(List<int> args);
+bool test(const List<int> &);
+
+int i = bar(List<int>());
+
+bool test(const List<int> &) {}