65 lines
1.9 KiB
Diff
65 lines
1.9 KiB
Diff
2008-03-25 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.
|
|
|
|
* g++.dg/ext/attrib33.C: New test.
|
|
|
|
--- gcc/cp/pt.c.jj 2008-03-10 17:11:48.000000000 +0100
|
|
+++ gcc/cp/pt.c 2008-03-25 21:32:17.000000000 +0100
|
|
@@ -6717,9 +6717,29 @@ apply_late_template_attributes (tree *de
|
|
{
|
|
*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);
|
|
}
|
|
--- gcc/testsuite/g++.dg/ext/attrib33.C.jj 2008-03-25 23:05:51.000000000 +0100
|
|
+++ gcc/testsuite/g++.dg/ext/attrib33.C 2008-03-25 23:06:15.000000000 +0100
|
|
@@ -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;
|