From: jason Date: Mon, 22 Oct 2007 18:03:10 +0000 (+0000) Subject: PR c++/33620 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=f00ae06e054459e3adf6a5f31baed4f13624f464;p=pf3gnuchains%2Fgcc-fork.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129553 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4283a88e249..903db53a323 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2007-10-22 Jason Merrill + + 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 * typeck.c (build_binary_op) : Use appropriate warning option diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4419813b6b6..54dc14c17ef 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 0a42b69ff4f..136c8dfd1ac 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 773c1041762..a54e90d6fa7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 index 00000000000..ee6c4184768 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/tmplattr7.C @@ -0,0 +1,11 @@ +// PR c++/33620 + +template +struct __attribute__((visibility("default"))) List {}; + +int bar(List args); +bool test(const List &); + +int i = bar(List()); + +bool test(const List &) {}