This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Abolish 'static' functions in local scope


GCC used to accept the following:

void foo() {
  static void bar();
}

There are three problems with this:

1. There are three possible meanings for it:
   A. This is a reference to a function foo() at the top level, which
      is local to this translation unit.
   B. This is a forward declaration of a nested function at this
      level, which would be named something like "foo.1" in the
      assembly; and that function can't access local variables of the
      routine (which distinguishes it from being 'auto').
   C. The 'static' should be ignored, making it a reference to a
      function foo() at the top level which is visible across all
      translation units.
   I believe all three exist in real code.  The last two exist in
   GCC's testsuite.  (A) exists in Apple's code base and
   the Linux kernel.

2. None of these three meanings actually works completely in current
   HEAD, or in 3.4; and the nature of the breakage is different in the
   two releases.

3. This extension isn't documented.  It's not even clear that it's
   intentional.  It is not used a lot; Apple's code base had only
   about 13 projects out of hundreds.

So, I'm taking it out.

I'm making it an error, because trying to use (A) generates invalid
assembly, (C) is useless, and (B) is both dangerous and useless.

Bootstrapped & tested on powerpc-darwin.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-staticlocalfunc.patch=================
2004-08-30  Geoffrey Keating  <geoffk@apple.com>

	PR 12738
	PR 17205
	Radar 3460526
	Radar 3775729
	* c-decl.c (grokdeclarator): Produce error for 'static' on local
	function declaration.

Index: testsuite/ChangeLog
2004-08-30  Geoffrey Keating  <geoffk@apple.com>

	* gcc.dg/funcdef-storage-1.c: New.
	* gcc.c-torture/compile/920625-2.c: Don't use 'static' to declare
	an extern function in local scope.
	* gcc.c-torture/execute/20010605-1.c: Don't use 'static inline' to
	declare an 'auto inline' function in local scope.
	* gcc.dg/20011130-1.c: Likewise.
	* gcc.c-torture/execute/nest-stdar-1.c: Don't use 'static' to declare
	an 'auto' function in local scope.
	* gcc.dg/20021014-1.c: Likewise.
	* gcc.dg/20030331-2.c: Likewise.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.564
diff -u -p -u -p -r1.564 c-decl.c
--- c-decl.c	26 Aug 2004 21:30:15 -0000	1.564
+++ c-decl.c	30 Aug 2004 21:56:27 -0000
@@ -4659,26 +4659,29 @@ grokdeclarator (tree declarator, tree de
       }
     else if (TREE_CODE (type) == FUNCTION_TYPE)
       {
-	if (specbits & (1 << (int) RID_AUTO)
-	    && (pedantic || current_scope == file_scope))
-	  pedwarn ("invalid storage class for function `%s'", name);
-	if (specbits & (1 << (int) RID_REGISTER))
+	if (specbits & (1 << (int) RID_REGISTER)
+	    || specbits & (1 << (int) RID_THREAD))
 	  error ("invalid storage class for function `%s'", name);
-	if (specbits & (1 << (int) RID_THREAD))
-	  error ("invalid storage class for function `%s'", name);
-	/* Function declaration not at file scope.
-	   Storage classes other than `extern' are not allowed
-	   and `extern' makes no difference.  */
-	if (current_scope != file_scope
-	    && (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
-	    && pedantic)
-	  pedwarn ("invalid storage class for function `%s'", name);
+	else if (current_scope != file_scope)
+	  {
+	    /* Function declaration not at file scope.  Storage
+	       classes other than `extern' are not allowed, C99
+	       6.7.1p5, and `extern' makes no difference.  However,
+	       GCC allows 'auto', perhaps with 'inline', to support
+	       nested functions.  */
+	    if (specbits & (1 << (int) RID_AUTO))
+	      {
+		if (pedantic)
+		  pedwarn ("invalid storage class for function `%s'", name);
+	      }
+	    if (specbits & (1 << (int) RID_STATIC))
+	      error ("invalid storage class for function `%s'", name);
+	  }
 
 	decl = build_decl (FUNCTION_DECL, declarator, type);
 	decl = build_decl_attribute_variant (decl, decl_attr);
 
-	DECL_LANG_SPECIFIC (decl)
-	  = GGC_CNEW (struct lang_decl);
+	DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
 
 	if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
 	  pedwarn ("ISO C forbids qualified function types");
Index: testsuite/gcc.c-torture/compile/920625-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/compile/920625-2.c,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 920625-2.c
--- testsuite/gcc.c-torture/compile/920625-2.c	16 Dec 1998 22:07:17 -0000	1.2
+++ testsuite/gcc.c-torture/compile/920625-2.c	30 Aug 2004 21:57:22 -0000
@@ -23,7 +23,7 @@ trashQueryResult(Widget w, Boolean delet
 
   extern Cursor busy, left_ptr;
   extern String cwd;
-      	static void freeReturnStruct(void);
+      	extern void freeReturnStruct(void);
   String rmstring;
   int status;
   XedwListReturnStruct *tmp;
@@ -58,7 +58,7 @@ copyQueryResult(Widget w, Boolean copy, 
   extern void destroy_button_dialog();
   extern void changestate(Boolean);
   extern Cursor busy, left_ptr;
-  static void freeReturnStruct(void);
+  extern void freeReturnStruct(void);
   int execute(String, String, String, Boolean);
   extern String cwd;
   String copystring;
Index: testsuite/gcc.c-torture/execute/20010605-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/20010605-1.c,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 20010605-1.c
--- testsuite/gcc.c-torture/execute/20010605-1.c	6 Jun 2001 03:08:21 -0000	1.2
+++ testsuite/gcc.c-torture/execute/20010605-1.c	30 Aug 2004 21:57:23 -0000
@@ -2,7 +2,7 @@ int main ()
 {
   int v = 42;
 
-  static inline int fff (int x)
+  inline int fff (int x)
     {
       return x*10;
     }
Index: testsuite/gcc.c-torture/execute/nest-stdar-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/nest-stdar-1.c,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 nest-stdar-1.c
--- testsuite/gcc.c-torture/execute/nest-stdar-1.c	16 Dec 1998 22:16:08 -0000	1.2
+++ testsuite/gcc.c-torture/execute/nest-stdar-1.c	30 Aug 2004 21:57:25 -0000
@@ -2,7 +2,7 @@
 
 main ()
 {
-  static double f (int x, ...)
+  double f (int x, ...)
     {
       va_list args;
       double a;
Index: testsuite/gcc.dg/20011130-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20011130-1.c,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 20011130-1.c
--- testsuite/gcc.dg/20011130-1.c	3 Dec 2001 14:23:01 -0000	1.1
+++ testsuite/gcc.dg/20011130-1.c	30 Aug 2004 21:57:27 -0000
@@ -9,7 +9,7 @@
 
 static int __attribute__((unused)) foo (int x)
 {
-  static inline int bar (int x)
+  inline int bar (int x)
     {
       int y;
       y = x;
Index: testsuite/gcc.dg/20021014-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20021014-1.c,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 20021014-1.c
--- testsuite/gcc.dg/20021014-1.c	21 Feb 2004 02:58:24 -0000	1.10
+++ testsuite/gcc.dg/20021014-1.c	30 Aug 2004 21:57:28 -0000
@@ -10,7 +10,7 @@ extern void exit (int);
 
 int foo (void)
 {
-  static int bar (int x)
+  int bar (int x)
   {
     return x + 3;
   }
Index: testsuite/gcc.dg/20030331-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20030331-2.c,v
retrieving revision 1.3
diff -u -p -u -p -r1.3 20030331-2.c
--- testsuite/gcc.dg/20030331-2.c	3 Aug 2004 08:22:21 -0000	1.3
+++ testsuite/gcc.dg/20030331-2.c	30 Aug 2004 21:57:28 -0000
@@ -6,7 +6,7 @@ int foo() {
   int yd;
   float in[1][yd];
  
-  static void bar() {
+  void bar() {
     printf("%p\n",in[0]);
   }
 }
Index: testsuite/gcc.dg/funcdef-storage-1.c
===================================================================
RCS file: testsuite/gcc.dg/funcdef-storage-1.c
diff -N testsuite/gcc.dg/funcdef-storage-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/funcdef-storage-1.c	30 Aug 2004 21:57:30 -0000
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+void
+flarm(void)
+{
+  static void foo();  /* { dg-error "invalid storage class" } */
+
+  foo();
+}
+
+static void
+foo(void)
+{
+}
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]