Commit 943f82e7 by Jason Merrill Committed by Jason Merrill

re PR c++/36625 (bogus error on __attribute__((aligned(N))) in template code)

	PR c++/36625
	* c-common.c (attribute_takes_identifier_p): New fn.
	* c-common.h: Declare it.
cp/
	* parser.c (cp_parser_parenthesized_expression_list): Change
	is_attribute_list parm to int to indicate whether or not to
	handle initial identifier specially.
	(cp_parser_attribute_list): Use attribute_takes_identifier_p.

From-SVN: r158355
parent 17fb1a8c
2010-04-14 Jason Merrill <jason@redhat.com>
PR c++/36625
* c-common.c (attribute_takes_identifier_p): New fn.
* c-common.h: Declare it.
2010-04-14 Uros Bizjak <ubizjak@gmail.com> 2010-04-14 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (*divmod<mode>4): Remove stray "&&" from * config/i386/i386.md (*divmod<mode>4): Remove stray "&&" from
......
...@@ -5809,6 +5809,17 @@ c_init_attributes (void) ...@@ -5809,6 +5809,17 @@ c_init_attributes (void)
#undef DEF_ATTR_TREE_LIST #undef DEF_ATTR_TREE_LIST
} }
/* Returns TRUE iff the attribute indicated by ATTR_ID takes a plain
identifier as an argument, so the front end shouldn't look it up. */
bool
attribute_takes_identifier_p (tree attr_id)
{
return (is_attribute_p ("mode", attr_id)
|| is_attribute_p ("format", attr_id)
|| is_attribute_p ("cleanup", attr_id));
}
/* Attribute handlers common to C front ends. */ /* Attribute handlers common to C front ends. */
/* Handle a "packed" attribute; arguments as in /* Handle a "packed" attribute; arguments as in
......
...@@ -822,6 +822,7 @@ extern void check_function_format (tree, int, tree *); ...@@ -822,6 +822,7 @@ extern void check_function_format (tree, int, tree *);
extern void set_Wformat (int); extern void set_Wformat (int);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *); extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
extern bool attribute_takes_identifier_p (tree);
extern int c_common_handle_option (size_t code, const char *arg, int value); extern int c_common_handle_option (size_t code, const char *arg, int value);
extern bool c_common_missing_argument (const char *opt, size_t code); extern bool c_common_missing_argument (const char *opt, size_t code);
extern tree c_common_type_for_mode (enum machine_mode, int); extern tree c_common_type_for_mode (enum machine_mode, int);
......
2010-04-14 Jason Merrill <jason@redhat.com>
PR c++/36625
* parser.c (cp_parser_parenthesized_expression_list): Change
is_attribute_list parm to int to indicate whether or not to
handle initial identifier specially.
(cp_parser_attribute_list): Use attribute_takes_identifier_p.
2010-04-13 Jason Merrill <jason@redhat.com> 2010-04-13 Jason Merrill <jason@redhat.com>
* call.c (type_decays_to): Check MAYBE_CLASS_TYPE_P instead of * call.c (type_decays_to): Check MAYBE_CLASS_TYPE_P instead of
......
...@@ -1596,7 +1596,9 @@ static tree cp_parser_postfix_open_square_expression ...@@ -1596,7 +1596,9 @@ static tree cp_parser_postfix_open_square_expression
static tree cp_parser_postfix_dot_deref_expression static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t); (cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
static VEC(tree,gc) *cp_parser_parenthesized_expression_list static VEC(tree,gc) *cp_parser_parenthesized_expression_list
(cp_parser *, bool, bool, bool, bool *); (cp_parser *, int, bool, bool, bool *);
/* Values for the second parameter of cp_parser_parenthesized_expression_list. */
enum { non_attr = 0, normal_attr = 1, id_attr = 2 };
static void cp_parser_pseudo_destructor_name static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *); (cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression static tree cp_parser_unary_expression
...@@ -4806,7 +4808,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, ...@@ -4806,7 +4808,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
parser->integral_constant_expression_p = false; parser->integral_constant_expression_p = false;
} }
args = (cp_parser_parenthesized_expression_list args = (cp_parser_parenthesized_expression_list
(parser, /*is_attribute_list=*/false, (parser, non_attr,
/*cast_p=*/false, /*allow_expansion_p=*/true, /*cast_p=*/false, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL)); /*non_constant_p=*/NULL));
if (is_builtin_constant_p) if (is_builtin_constant_p)
...@@ -5244,20 +5246,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ...@@ -5244,20 +5246,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
Returns a vector of trees. Each element is a representation of an Returns a vector of trees. Each element is a representation of an
assignment-expression. NULL is returned if the ( and or ) are assignment-expression. NULL is returned if the ( and or ) are
missing. An empty, but allocated, vector is returned on no missing. An empty, but allocated, vector is returned on no
expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is true expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr
if this is really an attribute list being parsed. If if we are parsing an attribute list for an attribute that wants a
plain identifier argument, normal_attr for an attribute that wants
an expression, or non_attr if we aren't parsing an attribute list. If
NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
not all of the expressions in the list were constant. */ not all of the expressions in the list were constant. */
static VEC(tree,gc) * static VEC(tree,gc) *
cp_parser_parenthesized_expression_list (cp_parser* parser, cp_parser_parenthesized_expression_list (cp_parser* parser,
bool is_attribute_list, int is_attribute_list,
bool cast_p, bool cast_p,
bool allow_expansion_p, bool allow_expansion_p,
bool *non_constant_p) bool *non_constant_p)
{ {
VEC(tree,gc) *expression_list; VEC(tree,gc) *expression_list;
bool fold_expr_p = is_attribute_list; bool fold_expr_p = is_attribute_list != non_attr;
tree identifier = NULL_TREE; tree identifier = NULL_TREE;
bool saved_greater_than_is_operator_p; bool saved_greater_than_is_operator_p;
...@@ -5284,7 +5288,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, ...@@ -5284,7 +5288,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
/* At the beginning of attribute lists, check to see if the /* At the beginning of attribute lists, check to see if the
next token is an identifier. */ next token is an identifier. */
if (is_attribute_list if (is_attribute_list == id_attr
&& cp_lexer_peek_token (parser->lexer)->type == CPP_NAME) && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
{ {
cp_token *token; cp_token *token;
...@@ -5345,7 +5349,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, ...@@ -5345,7 +5349,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
/* After the first item, attribute lists look the same as /* After the first item, attribute lists look the same as
expression lists. */ expression lists. */
is_attribute_list = false; is_attribute_list = non_attr;
get_comma:; get_comma:;
/* If the next token isn't a `,', then we are done. */ /* If the next token isn't a `,', then we are done. */
...@@ -5820,7 +5824,8 @@ cp_parser_new_placement (cp_parser* parser) ...@@ -5820,7 +5824,8 @@ cp_parser_new_placement (cp_parser* parser)
/* Parse the expression-list. */ /* Parse the expression-list. */
expression_list = (cp_parser_parenthesized_expression_list expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, (parser, non_attr, /*cast_p=*/false,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL)); /*non_constant_p=*/NULL));
return expression_list; return expression_list;
...@@ -6026,7 +6031,8 @@ cp_parser_new_initializer (cp_parser* parser) ...@@ -6026,7 +6031,8 @@ cp_parser_new_initializer (cp_parser* parser)
} }
else else
expression_list = (cp_parser_parenthesized_expression_list expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true, (parser, non_attr, /*cast_p=*/false,
/*allow_expansion_p=*/true,
/*non_constant_p=*/NULL)); /*non_constant_p=*/NULL));
return expression_list; return expression_list;
...@@ -9967,7 +9973,7 @@ cp_parser_mem_initializer (cp_parser* parser) ...@@ -9967,7 +9973,7 @@ cp_parser_mem_initializer (cp_parser* parser)
else else
{ {
VEC(tree,gc)* vec; VEC(tree,gc)* vec;
vec = cp_parser_parenthesized_expression_list (parser, false, vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/false, /*cast_p=*/false,
/*allow_expansion_p=*/true, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL); /*non_constant_p=*/NULL);
...@@ -15453,7 +15459,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, ...@@ -15453,7 +15459,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
else if (token->type == CPP_OPEN_PAREN) else if (token->type == CPP_OPEN_PAREN)
{ {
VEC(tree,gc) *vec; VEC(tree,gc) *vec;
vec = cp_parser_parenthesized_expression_list (parser, false, vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/false, /*cast_p=*/false,
/*allow_expansion_p=*/true, /*allow_expansion_p=*/true,
non_constant_p); non_constant_p);
...@@ -17768,8 +17774,10 @@ cp_parser_attribute_list (cp_parser* parser) ...@@ -17768,8 +17774,10 @@ cp_parser_attribute_list (cp_parser* parser)
if (token->type == CPP_OPEN_PAREN) if (token->type == CPP_OPEN_PAREN)
{ {
VEC(tree,gc) *vec; VEC(tree,gc) *vec;
int attr_flag = (attribute_takes_identifier_p (identifier)
? id_attr : normal_attr);
vec = cp_parser_parenthesized_expression_list vec = cp_parser_parenthesized_expression_list
(parser, true, /*cast_p=*/false, (parser, attr_flag, /*cast_p=*/false,
/*allow_expansion_p=*/false, /*allow_expansion_p=*/false,
/*non_constant_p=*/NULL); /*non_constant_p=*/NULL);
if (vec == NULL) if (vec == NULL)
...@@ -18971,7 +18979,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type) ...@@ -18971,7 +18979,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
} }
vec = cp_parser_parenthesized_expression_list (parser, false, vec = cp_parser_parenthesized_expression_list (parser, non_attr,
/*cast_p=*/true, /*cast_p=*/true,
/*allow_expansion_p=*/true, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL); /*non_constant_p=*/NULL);
......
2010-04-14 Jason Merrill <jason@redhat.com>
PR c++/36625
* g++.dg/ext/attrib38.C: New.
2010-04-14 Steve Ellcey <sje@cup.hp.com> 2010-04-14 Steve Ellcey <sje@cup.hp.com>
PR testsuite/43739 PR testsuite/43739
......
// PR c++/36625
template <int N>
struct A {
struct S { short f[3]; } __attribute__ ((aligned (N)));
};
int main ()
{
A<4>::S s;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment