diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-03-26 21:34:14 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-03-26 21:34:14 +0100 |
commit | ff2f1c5f22e9372be35ae5e03f5d9ada1c4e47da (patch) | |
tree | f3c00cfabb1e1de34ce1b74f9890ef3f2d44b1b8 | |
parent | 33558d947ce6fb40d78caaa208b394def95269b7 (diff) | |
download | gcc-ff2f1c5f22e9372be35ae5e03f5d9ada1c4e47da.zip gcc-ff2f1c5f22e9372be35ae5e03f5d9ada1c4e47da.tar.gz gcc-ff2f1c5f22e9372be35ae5e03f5d9ada1c4e47da.tar.bz2 |
re PR c++/35546 (__attribute__(format...) broken for members of template classes?)
PR c++/35546
* pt.c (apply_late_template_attributes): Don't call tsubst on
first attribute argument if it is IDENTIFIER_NODE.
* g++.dg/ext/attrib33.C: New test.
From-SVN: r133615
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attrib33.C | 18 |
4 files changed, 50 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 60eb1a3..447bfc0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2008-03-26 Jakub Jelinek <jakub@redhat.com> + PR c++/35546 + * pt.c (apply_late_template_attributes): Don't call tsubst on + first attribute argument if it is IDENTIFIER_NODE. + PR c++/35332 * error.c (dump_expr): Pass {,UN}ORDERED_EXPR, UN{LT,LE,GT,GE,EQ}_EXPR and LTGT_EXPR to pp_expression. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 67d392d..6f7efa6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6791,9 +6791,29 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, { *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); + /* If the first attribute argument is an identifier, don't + pass it through tsubst. Attributes like mode, format, + cleanup and several target specific attributes expect it + unmodified. */ + if (TREE_VALUE (t) + && TREE_CODE (TREE_VALUE (t)) == TREE_LIST + && TREE_VALUE (TREE_VALUE (t)) + && (TREE_CODE (TREE_VALUE (TREE_VALUE (t))) + == IDENTIFIER_NODE)) + { + tree chain + = tsubst_expr (TREE_CHAIN (TREE_VALUE (t)), args, complain, + in_decl, + /*integral_constant_expression_p=*/false); + if (chain != TREE_CHAIN (TREE_VALUE (t))) + TREE_VALUE (t) + = tree_cons (NULL_TREE, TREE_VALUE (TREE_VALUE (t)), + chain); + } + else + TREE_VALUE (t) + = tsubst_expr (TREE_VALUE (t), args, complain, in_decl, + /*integral_constant_expression_p=*/false); *q = t; q = &TREE_CHAIN (t); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ad8102..fda355c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-26 Jakub Jelinek <jakub@redhat.com> + + PR c++/35546 + * g++.dg/ext/attrib33.C: New test. + 2008-03-26 Richard Guenther <rguenther@suse.de> Revert diff --git a/gcc/testsuite/g++.dg/ext/attrib33.C b/gcc/testsuite/g++.dg/ext/attrib33.C new file mode 100644 index 0000000..5b98984 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib33.C @@ -0,0 +1,18 @@ +// PR c++/35546 +// { dg-do compile } + +template <int N> +struct T +{ + void foo (char const * ...) __attribute__ ((format (printf,2,3))); +}; + +template struct T<3>; + +template <typename T> +struct U +{ + typedef T __attribute__((mode (SI))) V; +}; + +U<int>::V v; |