Commit 84019f23 by Mark Mitchell Committed by Mark Mitchell

re PR c++/27648 (ICE on attribute on pointers in static_cast)

	PR c++/26748
	* parser.c (cp_parser_declarator): Robustify.
	PR c++/26748
	* g++.dg/ext/attrib22.C: New test.

From-SVN: r114667
parent 070809e3
2006-06-14 Mark Mitchell <mark@codesourcery.com> 2006-06-14 Mark Mitchell <mark@codesourcery.com>
PR c++/26748
* parser.c (cp_parser_declarator): Robustify.
PR c++/26559 PR c++/26559
* pt.c (tsubst_expr): Use finish_omp_atomic. * pt.c (tsubst_expr): Use finish_omp_atomic.
(value_dependent_expression_p): All CALL_EXPRs are dependent. (value_dependent_expression_p): All CALL_EXPRs are dependent.
......
...@@ -3374,12 +3374,12 @@ cp_parser_unqualified_id (cp_parser* parser, ...@@ -3374,12 +3374,12 @@ cp_parser_unqualified_id (cp_parser* parser,
qualifying_scope = parser->qualifying_scope; qualifying_scope = parser->qualifying_scope;
/* If the name is of the form "X::~X" it's OK. */ /* If the name is of the form "X::~X" it's OK. */
token = cp_lexer_peek_token (parser->lexer);
if (scope && TYPE_P (scope) if (scope && TYPE_P (scope)
&& cp_lexer_next_token_is (parser->lexer, CPP_NAME) && token->type == CPP_NAME
&& (cp_lexer_peek_nth_token (parser->lexer, 2)->type && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
== CPP_OPEN_PAREN) == CPP_OPEN_PAREN)
&& (cp_lexer_peek_token (parser->lexer)->value && constructor_name_p (token->value, scope))
== TYPE_IDENTIFIER (scope)))
{ {
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
return build_nt (BIT_NOT_EXPR, scope); return build_nt (BIT_NOT_EXPR, scope);
...@@ -3550,20 +3550,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -3550,20 +3550,6 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
cp_token_position start = 0; cp_token_position start = 0;
cp_token *token; cp_token *token;
/* If the next token corresponds to a nested name specifier, there
is no need to reparse it. However, if CHECK_DEPENDENCY_P is
false, it may have been true before, in which case something
like `A<X>::B<Y>::C' may have resulted in a nested-name-specifier
of `A<X>::', where it should now be `A<X>::B<Y>::'. So, when
CHECK_DEPENDENCY_P is false, we have to fall through into the
main loop. */
if (check_dependency_p
&& cp_lexer_next_token_is (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
{
cp_parser_pre_parsed_nested_name_specifier (parser);
return parser->scope;
}
/* Remember where the nested-name-specifier starts. */ /* Remember where the nested-name-specifier starts. */
if (cp_parser_uncommitted_to_tentative_parse_p (parser)) if (cp_parser_uncommitted_to_tentative_parse_p (parser))
{ {
...@@ -3663,6 +3649,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser, ...@@ -3663,6 +3649,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
class-or-namespace-name. */ class-or-namespace-name. */
parser->scope = old_scope; parser->scope = old_scope;
parser->qualifying_scope = saved_qualifying_scope; parser->qualifying_scope = saved_qualifying_scope;
if (cp_parser_uncommitted_to_tentative_parse_p (parser))
break;
/* If the next token is an identifier, and the one after /* If the next token is an identifier, and the one after
that is a `::', then any valid interpretation would have that is a `::', then any valid interpretation would have
found a class-or-namespace-name. */ found a class-or-namespace-name. */
...@@ -8797,10 +8785,19 @@ cp_parser_template_id (cp_parser *parser, ...@@ -8797,10 +8785,19 @@ cp_parser_template_id (cp_parser *parser,
template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments); template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
else if (DECL_CLASS_TEMPLATE_P (template) else if (DECL_CLASS_TEMPLATE_P (template)
|| DECL_TEMPLATE_TEMPLATE_PARM_P (template)) || DECL_TEMPLATE_TEMPLATE_PARM_P (template))
template_id {
= finish_template_type (template, arguments, bool entering_scope;
cp_lexer_next_token_is (parser->lexer, /* In "template <typename T> ... A<T>::", A<T> is the abstract A
template (rather than some instantiation thereof) only if
is not nested within some other construct. For example, in
"template <typename T> void f(T) { A<T>::", A<T> is just an
instantiation of A. */
entering_scope = (template_parm_scope_p ()
&& cp_lexer_next_token_is (parser->lexer,
CPP_SCOPE)); CPP_SCOPE));
template_id
= finish_template_type (template, arguments, entering_scope);
}
else else
{ {
/* If it's not a class-template or a template-template, it should be /* If it's not a class-template or a template-template, it should be
...@@ -11283,7 +11280,7 @@ cp_parser_declarator (cp_parser* parser, ...@@ -11283,7 +11280,7 @@ cp_parser_declarator (cp_parser* parser,
member_p); member_p);
} }
if (attributes && declarator != cp_error_declarator) if (attributes && declarator && declarator != cp_error_declarator)
declarator->attributes = attributes; declarator->attributes = attributes;
return declarator; return declarator;
......
2006-06-14 Mark Mitchell <mark@codesourcery.com> 2006-06-14 Mark Mitchell <mark@codesourcery.com>
PR c++/26748
* g++.dg/ext/attrib22.C: New test.
PR c++/26559 PR c++/26559
* g++.dg/template/builtin1.C: New test. * g++.dg/template/builtin1.C: New test.
* g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL. * g++.dg/gomp/tpl-atomic-2.C: Remove XFAIL.
// PR c++/27648
void f()
{
static_cast<float *__attribute((unused))>(0); // { dg-error "expected" }
}
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