C++ PATCH: PR 27884
Mark Mitchell
mark@codesourcery.com
Fri Jun 16 21:38:00 GMT 2006
This patch fixes PR c++/27884, a spurious error about uses of
"register" with the parameter list of an extern "C" function. In
fixing this bug, I realized that we can get rid of the age-old global
have_extern_spec; the parser now takes care of linkage specifications
itself.
Tested on x86_64-unknonwn-linux-gnu, applied on the mainline. I will
apply to 4.1 after testing completes.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-06-16 Mark Mitchell <mark@codesourcery.com>
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-16 Mark Mitchell <mark@codesourcery.com>
PR c++/27884
* g++.dg/parse/linkage2.C: New test
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c (revision 114647)
+++ gcc/cp/decl.c (working copy)
@@ -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 *declara
*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 *d
{
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. */
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 114703)
+++ gcc/cp/cp-tree.h (working copy)
@@ -3943,8 +3943,6 @@ extern void initialize_artificial_var (
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);
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 114667)
+++ gcc/cp/parser.c (working copy)
@@ -7732,9 +7732,7 @@ cp_parser_linkage_specification (cp_pars
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* pa
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
{
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->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+
return parameters;
}
Index: gcc/testsuite/g++.dg/parse/linkage2.C
===================================================================
--- gcc/testsuite/g++.dg/parse/linkage2.C (revision 0)
+++ gcc/testsuite/g++.dg/parse/linkage2.C (revision 0)
@@ -0,0 +1,3 @@
+// PR c++/27884
+
+extern "C" void foo(register int *my_perl);
More information about the Gcc-patches
mailing list