aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>2006-02-13 10:29:31 +0000
committerVolker Reichelt <reichelt@gcc.gnu.org>2006-02-13 10:29:31 +0000
commit28c84d634e56c98a867970eb62ce1224556ba7e1 (patch)
treeb0b40c8f3f492f75c60bf362ef71ada5b2c54f0b /gcc
parent5142e08b2f932ed958d703255ba5059b9192b037 (diff)
downloadgcc-28c84d634e56c98a867970eb62ce1224556ba7e1.zip
gcc-28c84d634e56c98a867970eb62ce1224556ba7e1.tar.gz
gcc-28c84d634e56c98a867970eb62ce1224556ba7e1.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl.c41
-rw-r--r--gcc/cp/parser.c40
3 files changed, 47 insertions, 42 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cbab739..fc53be0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index bb898b4..b00ac7a 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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)
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bba4d25..37df311 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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))