From ff2f1c5f22e9372be35ae5e03f5d9ada1c4e47da Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 26 Mar 2008 21:34:14 +0100 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/pt.c | 26 +++++++++++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/ext/attrib33.C | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attrib33.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 60eb1a35b9f..447bfc04117 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2008-03-26 Jakub Jelinek + 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 67d392da456..6f7efa6e55e 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 0ad8102a7ee..fda355c0217 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-26 Jakub Jelinek + + PR c++/35546 + * g++.dg/ext/attrib33.C: New test. + 2008-03-26 Richard Guenther Revert diff --git a/gcc/testsuite/g++.dg/ext/attrib33.C b/gcc/testsuite/g++.dg/ext/attrib33.C new file mode 100644 index 00000000000..5b989849128 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib33.C @@ -0,0 +1,18 @@ +// PR c++/35546 +// { dg-do compile } + +template +struct T +{ + void foo (char const * ...) __attribute__ ((format (printf,2,3))); +}; + +template struct T<3>; + +template +struct U +{ + typedef T __attribute__((mode (SI))) V; +}; + +U::V v; -- 2.30.2