Commit 28c84d63 by Volker Reichelt Committed by Volker Reichelt

re PR c++/26151 (duplicate 'duplicate' diagnostic)

	PR c++/26151
	* parser.c (cp_parser_decl_specifier_seq): Check for duplicate
	decl-specifiers.  Remove extra check for duplicate 'friend'.
	* decl.c (grokdeclarator): Remove check for duplicate
	decl-specifiers.  Set longlong together with long_p.

From-SVN: r110911
parent 5142e08b
2006-02-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/26151
* parser.c (cp_parser_decl_specifier_seq): Check for duplicate
decl-specifiers. Remove extra check for duplicate 'friend'.
* decl.c (grokdeclarator): Remove check for duplicate
decl-specifiers. Set longlong together with long_p.
2006-02-12 Jason Merrill <jason@redhat.com> 2006-02-12 Jason Merrill <jason@redhat.com>
PR c++/24996 PR c++/24996
......
...@@ -6662,7 +6662,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6662,7 +6662,6 @@ grokdeclarator (const cp_declarator *declarator,
this value will be NULL_TREE, even if the entity is located at this value will be NULL_TREE, even if the entity is located at
namespace scope. */ namespace scope. */
tree in_namespace = NULL_TREE; tree in_namespace = NULL_TREE;
cp_decl_spec ds;
cp_storage_class storage_class; cp_storage_class storage_class;
bool unsigned_p, signed_p, short_p, long_p, thread_p; bool unsigned_p, signed_p, short_p, long_p, thread_p;
bool type_was_error_mark_node = false; bool type_was_error_mark_node = false;
...@@ -6671,6 +6670,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6671,6 +6670,7 @@ grokdeclarator (const cp_declarator *declarator,
unsigned_p = declspecs->specs[(int)ds_unsigned]; unsigned_p = declspecs->specs[(int)ds_unsigned];
short_p = declspecs->specs[(int)ds_short]; short_p = declspecs->specs[(int)ds_short];
long_p = declspecs->specs[(int)ds_long]; long_p = declspecs->specs[(int)ds_long];
longlong = declspecs->specs[(int)ds_long] >= 2;
thread_p = declspecs->specs[(int)ds_thread]; thread_p = declspecs->specs[(int)ds_thread];
if (decl_context == FUNCDEF) if (decl_context == FUNCDEF)
...@@ -6884,45 +6884,6 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6884,45 +6884,6 @@ grokdeclarator (const cp_declarator *declarator,
explicit_int = declspecs->explicit_int_p; explicit_int = declspecs->explicit_int_p;
explicit_char = declspecs->explicit_char_p; explicit_char = declspecs->explicit_char_p;
/* Check for repeated decl-specifiers. */
for (ds = ds_first; ds != ds_last; ++ds)
{
unsigned count = declspecs->specs[(int)ds];
if (count < 2)
continue;
/* The "long" specifier is a special case because of
"long long". */
if (ds == ds_long)
{
if (count > 2)
error ("%<long long long%> is too long for GCC");
else if (pedantic && !in_system_header && warn_long_long)
pedwarn ("ISO C++ does not support %<long long%>");
else
longlong = 1;
}
else if (declspecs->specs[(int)ds] > 1)
{
static const char *const decl_spec_names[] = {
"signed",
"unsigned",
"short",
"long",
"const",
"volatile",
"restrict",
"inline",
"virtual",
"explicit",
"friend",
"typedef",
"__complex",
"__thread"
};
error ("duplicate %qs", decl_spec_names[(int)ds]);
}
}
#if 0 #if 0
/* See the code below that used this. */ /* See the code below that used this. */
if (typedef_decl) if (typedef_decl)
......
...@@ -7330,6 +7330,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -7330,6 +7330,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
int* declares_class_or_enum) int* declares_class_or_enum)
{ {
bool constructor_possible_p = !parser->in_declarator_p; bool constructor_possible_p = !parser->in_declarator_p;
cp_decl_spec ds;
/* Clear DECL_SPECS. */ /* Clear DECL_SPECS. */
clear_decl_specs (decl_specs); clear_decl_specs (decl_specs);
...@@ -7364,8 +7365,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -7364,8 +7365,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* decl-specifier: /* decl-specifier:
friend */ friend */
case RID_FRIEND: case RID_FRIEND:
if (decl_specs->specs[(int) ds_friend]++) ++decl_specs->specs[(int) ds_friend];
error ("duplicate %<friend%>");
/* Consume the token. */ /* Consume the token. */
cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer);
break; break;
...@@ -7531,6 +7531,42 @@ cp_parser_decl_specifier_seq (cp_parser* parser, ...@@ -7531,6 +7531,42 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
flags |= CP_PARSER_FLAGS_OPTIONAL; flags |= CP_PARSER_FLAGS_OPTIONAL;
} }
/* Check for repeated decl-specifiers. */
for (ds = ds_first; ds != ds_last; ++ds)
{
unsigned count = decl_specs->specs[(int)ds];
if (count < 2)
continue;
/* The "long" specifier is a special case because of "long long". */
if (ds == ds_long)
{
if (count > 2)
error ("%<long long long%> is too long for GCC");
else if (pedantic && !in_system_header && warn_long_long)
pedwarn ("ISO C++ does not support %<long long%>");
}
else if (count > 1)
{
static const char *const decl_spec_names[] = {
"signed",
"unsigned",
"short",
"long",
"const",
"volatile",
"restrict",
"inline",
"virtual",
"explicit",
"friend",
"typedef",
"__complex",
"__thread"
};
error ("duplicate %qs", decl_spec_names[(int)ds]);
}
}
/* Don't allow a friend specifier with a class definition. */ /* Don't allow a friend specifier with a class definition. */
if (decl_specs->specs[(int) ds_friend] != 0 if (decl_specs->specs[(int) ds_friend] != 0
&& (*declares_class_or_enum & 2)) && (*declares_class_or_enum & 2))
......
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