[C++ PATCH] Fix handling of late template attribute arguments (PR c++/35546)
Jakub Jelinek
jakub@redhat.com
Wed Mar 26 06:40:00 GMT 2008
Hi!
If the first attribute argument is IDENTIFIER_NODE, it expects
it to be kept as such, doesn't need to be nor should be looked up.
Even the C++ parser handles them specially in
cp_parser_parenthesized_expression_list - if first argument
is IDENTIFIER_NODE, it is parsed as such, otherwise it is parsed
as assignment-expression. The second and following arguments
are always parsed as assignment-expression.
When apply_late_template_attributes calls tsubst_expr on the whole
TREE_LIST with the arguments, tsubst_copy_and_build will try to
look up that IDENTIFIER_NODE, issue inappropriate errors etc.
I've looked at all attributes that take arguments. IDENTIFIER_NODE
in first argument is expected in mode, format, cleanup generic
attributes and then a few target specific ones - ia64 and m32r model
attribute and ppc altivec attribute.
Fixed thusly, ok for trunk/4.3 if bootstrap/regtest on x86_64-linux
passes?
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;
Jakub
More information about the Gcc-patches
mailing list