OSDN Git Service

PR c++/33620
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Oct 2007 18:03:10 +0000 (18:03 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Oct 2007 18:03:10 +0000 (18:03 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129553 138bc75d-0d04-0410-961f-82ee72b054a4

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 4283a88..903db53 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 4419813..54dc14c 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 0a42b69..136c8df 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 773c104..a54e90d 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> &) {}