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
This commit is contained in:
Volker Reichelt 2006-02-13 10:29:31 +00:00 committed by Volker Reichelt
parent 5142e08b2f
commit 28c84d634e
3 changed files with 47 additions and 42 deletions

View File

@ -1,3 +1,11 @@
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>
PR c++/24996

View File

@ -6662,7 +6662,6 @@ grokdeclarator (const cp_declarator *declarator,
this value will be NULL_TREE, even if the entity is located at
namespace scope. */
tree in_namespace = NULL_TREE;
cp_decl_spec ds;
cp_storage_class storage_class;
bool unsigned_p, signed_p, short_p, long_p, thread_p;
bool type_was_error_mark_node = false;
@ -6671,6 +6670,7 @@ grokdeclarator (const cp_declarator *declarator,
unsigned_p = declspecs->specs[(int)ds_unsigned];
short_p = declspecs->specs[(int)ds_short];
long_p = declspecs->specs[(int)ds_long];
longlong = declspecs->specs[(int)ds_long] >= 2;
thread_p = declspecs->specs[(int)ds_thread];
if (decl_context == FUNCDEF)
@ -6884,45 +6884,6 @@ grokdeclarator (const cp_declarator *declarator,
explicit_int = declspecs->explicit_int_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
/* See the code below that used this. */
if (typedef_decl)

View File

@ -7330,6 +7330,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
int* declares_class_or_enum)
{
bool constructor_possible_p = !parser->in_declarator_p;
cp_decl_spec ds;
/* Clear DECL_SPECS. */
clear_decl_specs (decl_specs);
@ -7364,8 +7365,7 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* decl-specifier:
friend */
case RID_FRIEND:
if (decl_specs->specs[(int) ds_friend]++)
error ("duplicate %<friend%>");
++decl_specs->specs[(int) ds_friend];
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
break;
@ -7531,6 +7531,42 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
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. */
if (decl_specs->specs[(int) ds_friend] != 0
&& (*declares_class_or_enum & 2))