diff options
author | Volker Reichelt <reichelt@igpm.rwth-aachen.de> | 2006-07-15 09:44:36 +0000 |
---|---|---|
committer | Volker Reichelt <reichelt@gcc.gnu.org> | 2006-07-15 09:44:36 +0000 |
commit | 856367df0880f605404ff9fc0ddf1420525ef61d (patch) | |
tree | 82833ed6777c99fa879281c80b54c5a9054a3f51 /gcc | |
parent | 0a9367cbdbdc9e5302e7ac39b00c26e698c4100d (diff) | |
download | gcc-856367df0880f605404ff9fc0ddf1420525ef61d.zip gcc-856367df0880f605404ff9fc0ddf1420525ef61d.tar.gz gcc-856367df0880f605404ff9fc0ddf1420525ef61d.tar.bz2 |
re PR c++/28249 ("long long long" accepted by catch)
PR c++/28249
* parser.c (cp_parser_check_decl_spec): New function.
(cp_parser_decl_specifier_seq): Factor out check for repeated
decl-specifiers into cp_parser_check_decl_spec. Use it.
(cp_parser_type_specifier_seq) Use it.
* g++.dg/parse/catch1.C: New test.
From-SVN: r115469
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 82 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/catch1.C | 8 |
4 files changed, 63 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fe5d0c7..aa508e3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2006-07-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + PR c++/28249 + * parser.c (cp_parser_check_decl_spec): New function. + (cp_parser_decl_specifier_seq): Factor out check for repeated + decl-specifiers into cp_parser_check_decl_spec. Use it. + (cp_parser_type_specifier_seq) Use it. + PR c++/28294 * semantics.c (finish_offsetof): Use TREE_OPERAND for COMPONENT_REFs only. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 63a6b88..81000bf 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1950,6 +1950,49 @@ cp_parser_simulate_error (cp_parser* parser) return false; } +/* Check for repeated decl-specifiers. */ + +static void +cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs) +{ + cp_decl_spec ds; + + 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]); + } + } +} + /* This function is called when a type is defined. If type definitions are forbidden at this point, an error message is issued. */ @@ -7376,7 +7419,6 @@ 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); @@ -7559,41 +7601,7 @@ 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]); - } - } + cp_parser_check_decl_spec (decl_specs); /* Don't allow a friend specifier with a class definition. */ if (decl_specs->specs[(int) ds_friend] != 0 @@ -12030,6 +12038,8 @@ cp_parser_type_specifier_seq (cp_parser* parser, if (is_condition && !is_cv_qualifier) flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES; } + + cp_parser_check_decl_spec (type_specifier_seq); } /* Parse a parameter-declaration-clause. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6a2a4b5..c145b16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2006-07-15 Volker Reichelt <reichelt@igpm.rwth-aachen.de> + PR c++/28249 + * g++.dg/parse/catch1.C: New test. + PR c++/28294 * g++.dg/ext/offsetof1.C: Add test with function pointer arithmetic. diff --git a/gcc/testsuite/g++.dg/parse/catch1.C b/gcc/testsuite/g++.dg/parse/catch1.C new file mode 100644 index 0000000..8774022 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/catch1.C @@ -0,0 +1,8 @@ +// PR c++/28249 +// { dg-do compile } + +void foo() +{ + try {} + catch (long long long) {} // { dg-error "long long long" } +} |