From 75a829785fbfeedcb435e7aa3b43d96ad44926b0 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 16 Jun 2006 18:45:50 +0000 Subject: [PATCH] re PR c++/27884 (bogus error: invalid use of 'register' in linkage specification) PR c++/27884 * decl.c (have_extern_spec): Remove. (start_decl): Do not check have_extern_spec. (start_function): Likewise. * cp-tree.h (have_extern_spec): Remove. * parser.c (cp_parser_linkage_specification): Don't set have_extern_spec. (cp_parser_init_declarator): Likewise. (cp_parser_parameter_declaration): Do not treat parameters as within the scope of an unbraced linkage specification. PR c++/27884 * g++.dg/parse/linkage2.C: New test From-SVN: r114727 --- gcc/cp/ChangeLog | 13 +++++++++++++ gcc/cp/cp-tree.h | 2 -- gcc/cp/decl.c | 18 ------------------ gcc/cp/parser.c | 17 +++++++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/parse/linkage2.C | 3 +++ 6 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/linkage2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bb1ea7f9ffc..28e17099b2f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2006-06-16 Mark Mitchell + + PR c++/27884 + * decl.c (have_extern_spec): Remove. + (start_decl): Do not check have_extern_spec. + (start_function): Likewise. + * cp-tree.h (have_extern_spec): Remove. + * parser.c (cp_parser_linkage_specification): Don't set + have_extern_spec. + (cp_parser_init_declarator): Likewise. + (cp_parser_parameter_declaration): Do not treat parameters as + within the scope of an unbraced linkage specification. + 2006-06-15 Mark Mitchell PR c++/27689 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e9f28a6f6e4..4e4d8ec7f62 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3943,8 +3943,6 @@ extern void initialize_artificial_var (tree, tree); extern tree check_var_type (tree, tree); extern tree reshape_init (tree, tree); -extern bool have_extern_spec; - /* in decl2.c */ extern bool check_java_method (tree); extern tree build_memfn_type (tree, tree, cp_cv_quals); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2d92fe382d5..7db989d82a5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -240,10 +240,6 @@ enum deprecated_states { static enum deprecated_states deprecated_state = DEPRECATED_NORMAL; -/* True if a declaration with an `extern' linkage specifier is being - processed. */ -bool have_extern_spec; - /* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the @@ -3814,13 +3810,6 @@ start_decl (const cp_declarator *declarator, *pushed_scope_p = NULL_TREE; - /* This should only be done once on the top most decl. */ - if (have_extern_spec) - { - declspecs->storage_class = sc_extern; - have_extern_spec = false; - } - /* An object declared as __attribute__((deprecated)) suppresses warnings of uses of other deprecated items. */ if (lookup_attribute ("deprecated", attributes)) @@ -10632,13 +10621,6 @@ start_function (cp_decl_specifier_seq *declspecs, { tree decl1; - if (have_extern_spec) - { - declspecs->storage_class = sc_extern; - /* This should only be done once on the outermost decl. */ - have_extern_spec = false; - } - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs); /* If the declarator is not suitable for a function definition, cause a syntax error. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index df175fa21ae..964ab0ee738 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7732,9 +7732,7 @@ cp_parser_linkage_specification (cp_parser* parser) saved_in_unbraced_linkage_specification_p = parser->in_unbraced_linkage_specification_p; parser->in_unbraced_linkage_specification_p = true; - have_extern_spec = true; cp_parser_declaration (parser); - have_extern_spec = false; parser->in_unbraced_linkage_specification_p = saved_in_unbraced_linkage_specification_p; } @@ -11063,10 +11061,7 @@ cp_parser_init_declarator (cp_parser* parser, if (!member_p) { if (parser->in_unbraced_linkage_specification_p) - { - decl_specifiers->storage_class = sc_extern; - have_extern_spec = false; - } + decl_specifiers->storage_class = sc_extern; decl = start_decl (declarator, decl_specifiers, is_initialized, attributes, prefix_attributes, &pushed_scope); @@ -12119,9 +12114,16 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) { cp_parameter_declarator *parameters = NULL; cp_parameter_declarator **tail = ¶meters; + bool saved_in_unbraced_linkage_specification_p; /* Assume all will go well. */ *is_error = false; + /* The special considerations that apply to a function within an + unbraced linkage specifications do not apply to the parameters + to the function. */ + saved_in_unbraced_linkage_specification_p + = parser->in_unbraced_linkage_specification_p; + parser->in_unbraced_linkage_specification_p = false; /* Look for more parameters. */ while (true) @@ -12200,6 +12202,9 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) } } + parser->in_unbraced_linkage_specification_p + = saved_in_unbraced_linkage_specification_p; + return parameters; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f4a6ed447e4..a1eba47192b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-06-16 Mark Mitchell + + PR c++/27884 + * g++.dg/parse/linkage2.C: New test + 2006-06-16 Richard Guenther PR middle-end/27116 diff --git a/gcc/testsuite/g++.dg/parse/linkage2.C b/gcc/testsuite/g++.dg/parse/linkage2.C new file mode 100644 index 00000000000..aa204df2a10 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/linkage2.C @@ -0,0 +1,3 @@ +// PR c++/27884 + +extern "C" void foo(register int *my_perl); -- 2.30.2