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