This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/33620
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 22 Oct 2007 14:01:58 -0400
- Subject: C++ PATCH for c++/33620
Now that I'm propagating attributes from template to instantiation, it
turns out that we also need to propagate them to cv-variants.
The decl.c hunk is an unrelated minor cleanup that I noticed while
poking at 15764.
Tested x86_64-pc-linux-gnu, applied to trunk.
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.
Index: cp/class.c
===================================================================
*** cp/class.c (revision 129215)
--- cp/class.c (working copy)
*************** finish_struct_bits (tree t)
*** 1452,1457 ****
--- 1452,1460 ----
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: cp/pt.c
===================================================================
*** cp/pt.c (revision 129215)
--- cp/pt.c (working copy)
*************** static void
*** 6486,6508 ****
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 t;
if (DECL_P (*decl_p))
! DECL_ATTRIBUTES (*decl_p) = attributes;
else
! TYPE_ATTRIBUTES (*decl_p) = attributes;
! 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);
! cplus_decl_attributes (decl_p, late_attrs, attr_flags);
}
tree
--- 6486,6532 ----
apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
tree args, tsubst_flags_t complain, tree in_decl)
{
! 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))
! p = &DECL_ATTRIBUTES (*decl_p);
else
! p = &TYPE_ATTRIBUTES (*decl_p);
! if (last_dep)
! {
! tree late_attrs = NULL_TREE;
! tree *q = &late_attrs;
! 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
Index: cp/decl.c
===================================================================
*** cp/decl.c (revision 129215)
--- cp/decl.c (working copy)
*************** cxx_maybe_build_cleanup (tree decl)
*** 12121,12130 ****
if (TREE_CODE (type) == ARRAY_TYPE)
addr = decl;
else
! {
! cxx_mark_addressable (decl);
! addr = build_unary_op (ADDR_EXPR, decl, 0);
! }
/* Optimize for space over speed here. */
if (!has_vbases || flag_expensive_optimizations)
--- 12121,12127 ----
if (TREE_CODE (type) == ARRAY_TYPE)
addr = decl;
else
! addr = build_address (decl);
/* Optimize for space over speed here. */
if (!has_vbases || flag_expensive_optimizations)
Index: testsuite/g++.dg/ext/tmplattr7.C
===================================================================
*** testsuite/g++.dg/ext/tmplattr7.C (revision 0)
--- testsuite/g++.dg/ext/tmplattr7.C (revision 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> &) {}