Patch to -Wtraditional to detect ISO C style function definitions

Kaveh R. Ghazi ghazi@caip.rutgers.edu
Mon Jul 1 07:54:00 GMT 2002


This patch adds the capability to detect ISO C style function
definitions with -Wtraditional.  This would have supposedly detected
the traditional C problem in 3.1.0 which prevented gcc bootstrapping
on hpux with cc.  It also reveal new problems that have crept into
3.2 so we can fix them prior to the release.

This is an updated version of:
http://gcc.gnu.org/ml/gcc-patches/2002-03/msg00355.html
Thanks to Neil and Alex for your feedback.  I think I've solved all of
the potential issues.

Notes:

1.  The number of shift/reduce conflicts went *down* by two for both C
    and objc.  (I don't know if that's a bug or a feature.)

2.  It doesn't warn for prototypes or variadic functions since these
    are (expected to be) passed through in ISO C style via PARAMS and
    VPARAMS when compiling code with gcc.  It wouldn't be useful to
    warn about them as we'd get lots of false positives.

3.  It also doesn't warn for nested functions using ISO C style since
    these are already a gcc specific extention and would have to be
    guarded with macro checks to work on a traditional C compiler
    anyway.

4.  I had to fix a bunch of the other -Wtraditional tests to stop
    using ISO C style function defs so they wouldn't spuriously fail.
    It was a good positive confirm that the patch actually works. :-)

5.  Another positive confirm, bootstrapping with the patch reveals 23
    spots using ISO C style.  Of these 16 are from flex generated
    output, the rest were human inserted mostly appearing in code new
    to 3.2.  I'll submit a fix for these after this patch goes in.

Bootstrapped on sparc-sun-solaris2.7, no testsuite regressions and the
new testcase passes.

Ok to install?

		Thanks,
		--Kaveh


2002-06-30  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* c-parse.in (parsing_iso_function_signature): New variable.
	(extdef_1): New, copied from...
	(extdef): ... here.  Reset parsing_iso_function_signature.
	(old_style_parm_decls_1): New, copied from...
	(old_style_parm_decls): ...here.  Warn about ISO C style function
	definitions and reset parsing_iso_function_signature.
	(nested_function, notype_nested_function): Reset
	parsing_iso_function_signature.
	(parmlist_2): Set parsing_iso_function_signature.

	* doc/invoke.texi (-Wtraditional): Document new behavior.

testsuite:
	* gcc.dg/cpp/tr-warn2.c: Use traditional C style function definitions.
	* gcc.dg/wtr-aggr-init-1.c: Likewise.
	* gcc.dg/wtr-conversion-1.c: Likewise.
	* gcc.dg/wtr-escape-1.c: Likewise.
	* gcc.dg/wtr-int-type-1.c: Likewise.
	* gcc.dg/wtr-label-1.c: Likewise.
	* gcc.dg/wtr-static-1.c: Likewise.
	* gcc.dg/wtr-strcat-1.c: Likewise.
	* gcc.dg/wtr-suffix-1.c: Likewise.
	* gcc.dg/wtr-switch-1.c: Likewise.
	* gcc.dg/wtr-unary-plus-1.c: Likewise.
	* gcc.dg/wtr-union-init-1.c: Likewise.
	* gcc.dg/wtr-union-init-2.c: Likewise.
	* gcc.dg/wtr-union-init-3.c: Likewise.

	* gcc.dg/wtr-func-def-1.c: New test.

diff -rup orig/egcc-CVS20020630/gcc/c-parse.in egcc-CVS20020630/gcc/c-parse.in
--- orig/egcc-CVS20020630/gcc/c-parse.in	Thu Jun 20 07:01:03 2002
+++ egcc-CVS20020630/gcc/c-parse.in	Sun Jun 30 21:12:44 2002
@@ -331,6 +331,8 @@ ifc
 #define OBJC_NEED_RAW_IDENTIFIER(VAL)	/* nothing */
 end ifc
 
+static bool parsing_iso_function_signature;
+
 /* Tell yyparse how to print a token's value, if yydebug is set.  */
 
 #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
@@ -382,6 +384,10 @@ extdefs:
 	;
 
 extdef:
+	extdef_1
+	{ parsing_iso_function_signature = false; } /* Reset after any external definition.  */
+
+extdef_1:
 	fndef
 	| datadef
 ifobjc
@@ -787,6 +793,17 @@ objc_string:
 end ifobjc
 
 old_style_parm_decls:
+	{
+	  if (warn_traditional && !in_system_header
+	      && parsing_iso_function_signature)
+	    {
+	      warning ("traditional C rejects ISO C style function definitions");
+	      parsing_iso_function_signature = false; /* Reset after warning.  */
+	    }
+	}
+	old_style_parm_decls_1
+
+old_style_parm_decls_1:
 	/* empty */
 	| datadecls
 	| datadecls ELLIPSIS
@@ -1591,6 +1608,7 @@ nested_function:
 		      pop_function_context ();
 		      YYERROR1;
 		    }
+		  parsing_iso_function_signature = false; /* Don't warn about nested functions.  */
 		}
 	   old_style_parm_decls
 		{ store_parm_decls (); }
@@ -1621,6 +1639,7 @@ notype_nested_function:
 		      pop_function_context ();
 		      YYERROR1;
 		    }
+		  parsing_iso_function_signature = false; /* Don't warn about nested functions.  */
 		}
 	  old_style_parm_decls
 		{ store_parm_decls (); }
@@ -2545,7 +2564,9 @@ parmlist_2:  /* empty */
 		  error ("ISO C requires a named argument before `...'");
 		}
 	| parms
-		{ $$ = get_parm_info (1); }
+		{ $$ = get_parm_info (1);
+		  parsing_iso_function_signature = true;
+		}
 	| parms ',' ELLIPSIS
 		{ $$ = get_parm_info (0); }
 	;
diff -rup orig/egcc-CVS20020630/gcc/doc/invoke.texi egcc-CVS20020630/gcc/doc/invoke.texi
--- orig/egcc-CVS20020630/gcc/doc/invoke.texi	Sun Jun 30 15:05:09 2002
+++ egcc-CVS20020630/gcc/doc/invoke.texi	Sun Jun 30 21:27:31 2002
@@ -2410,6 +2410,15 @@ Conversions by prototypes between fixed/
 versa.  The absence of these prototypes when compiling with traditional
 C would cause serious problems.  This is a subset of the possible
 conversion warnings, for the full set use @option{-Wconversion}.
+
+@item
+Use of ISO C style function definitions.  This warning intentionally is
+@emph{not} issued for prototype declarations or variadic functions
+because these ISO C features will appear in your code when using
+libiberty's traditional C compatibility macros, @code{PARAMS} and
+@code{VPARAMS}.  This warning is also bypassed for nested functions
+because that feature is already a gcc extension and thus not relevant to
+traditional C compatibility.
 @end itemize
 
 @item -Wundef
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/cpp/tr-warn2.c egcc-CVS20020630/gcc/testsuite/gcc.dg/cpp/tr-warn2.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/cpp/tr-warn2.c	Tue Jun 27 18:26:11 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/cpp/tr-warn2.c	Sun Jun 30 21:30:30 2002
@@ -8,7 +8,7 @@ enum { SIGN_EXTEND = 23 };
 
 #define SIGN_EXTEND(v) (((v) < 0) ? -1 : 0)
 
-int fun(void)
+int fun()
 {
   return SIGN_EXTEND;	/* { dg-warning "must be used with arguments" } */
 }
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-aggr-init-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-aggr-init-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-aggr-init-1.c	Fri Dec 21 16:30:29 2001
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-aggr-init-1.c	Sun Jun 30 21:31:39 2002
@@ -14,7 +14,7 @@ struct foo f0 = { 0, 0 };
 static struct foo f1 = { 0, 0 };
 
 void
-testfunc1 (void)
+testfunc1 ()
 {
   struct foo f3 = { 0, 0 }; /* { dg-warning "traditional C rejects automatic" "automatic aggregate initialization" } */
   static struct foo f4 = { 0, 0 };
@@ -39,7 +39,7 @@ struct foo f7 = { 0, 0 };
 static struct foo f8 = { 0, 0 };
 
 void
-testfunc2 (void)
+testfunc2 ()
 {
   struct foo f9 = { 0, 0 };
   static struct foo f10 = { 0, 0 };
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-conversion-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-conversion-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-conversion-1.c	Mon Apr 16 22:21:10 2001
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-conversion-1.c	Sun Jun 30 21:31:23 2002
@@ -15,7 +15,7 @@ extern long double ld;
 extern __complex__ double cd;
 
 void
-testfunc1 (void)
+testfunc1 ()
 {
   foo_i (i);
   foo_i (f); /* { dg-warning "as integer rather than floating" "prototype conversion warning" } */
@@ -42,7 +42,7 @@ testfunc1 (void)
 /* We are in system headers now, no -Wtraditional warnings should issue.  */
 
 void
-testfunc2 (void)
+testfunc2 ()
 {
   foo_i (i);
   foo_i (f);
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-escape-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-escape-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-escape-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-escape-1.c	Sun Jun 30 21:32:01 2002
@@ -5,7 +5,7 @@
 /* { dg-options "-Wtraditional" } */
 
 void
-testfunc (void)
+testfunc ()
 {
   char c;
 
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-int-type-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-int-type-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-int-type-1.c	Sun Jun  2 16:01:11 2002
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-int-type-1.c	Sun Jun 30 21:32:18 2002
@@ -5,7 +5,7 @@
 /* { dg-options "-std=c99 -Wtraditional" } */
 
 void
-testfunc (void)
+testfunc ()
 {
   long long i;
   
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-label-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-label-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-label-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-label-1.c	Sun Jun 30 21:32:53 2002
@@ -11,7 +11,8 @@ int foo4;
 typedef int foo5;
 
 void
-testfunc1 (int foo6)
+testfunc1 (foo6)
+     int foo6;
 {
   int foo7;
 
@@ -32,7 +33,8 @@ testfunc1 (int foo6)
 /* We are in system headers now, no -Wtraditional warnings should issue.  */
 
 void
-testfunc2 (int foo6)
+testfunc2 (foo6)
+     int foo6;
 {
   int foo7;
 
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-static-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-static-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-static-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-static-1.c	Sun Jun 30 21:33:18 2002
@@ -5,10 +5,10 @@
 /* { dg-options "-Wtraditional" } */
 
 static void testfunc1(void);
-void testfunc1(void) {} /* { dg-warning "non-static.*follows static" "non-static follows static" } */
+void testfunc1() {} /* { dg-warning "non-static.*follows static" "non-static follows static" } */
 
 # 11 "sys-header.h" 3
 /* We are in system headers now, no -Wtraditional warnings should issue.  */
 
 static void testfunc2(void);
-void testfunc2(void) {}
+void testfunc2() {}
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-strcat-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-strcat-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-strcat-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-strcat-1.c	Sun Jun 30 21:33:31 2002
@@ -5,7 +5,7 @@
 /* { dg-options "-Wtraditional" } */
 
 void
-testfunc (void)
+testfunc ()
 {
   const char *foo;
   
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-suffix-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-suffix-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-suffix-1.c	Sun Jun  2 16:01:11 2002
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-suffix-1.c	Sun Jun 30 21:33:42 2002
@@ -5,7 +5,7 @@
 /* { dg-options "-Wtraditional" } */
 
 void
-testfunc (void)
+testfunc ()
 {
   int i;
   double f;
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-switch-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-switch-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-switch-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-switch-1.c	Sun Jun 30 21:33:56 2002
@@ -5,7 +5,8 @@
 /* { dg-options "-Wtraditional" } */
 
 void
-testfunc (long l)
+testfunc (l)
+     long l;
 {
   switch (l) /* { dg-warning "switch expression" "switch expression" } */
   {
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-unary-plus-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-unary-plus-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-unary-plus-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-unary-plus-1.c	Sun Jun 30 21:34:11 2002
@@ -5,7 +5,7 @@
 /* { dg-options "-Wtraditional" } */
 
 void
-testfunc (void)
+testfunc ()
 {
   int i;
   
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-1.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-1.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-1.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-1.c	Sun Jun 30 21:34:24 2002
@@ -11,7 +11,7 @@ union foo
 };
 
 void
-testfunc (void)
+testfunc ()
 {
   /* Note we only warn for non-zero initializers.  */
   static union foo f1 = { 0 };
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-2.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-2.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-2.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-2.c	Sun Jun 30 21:34:36 2002
@@ -19,7 +19,7 @@ union foo2
 };
 
 void
-testfunc (void)
+testfunc ()
 {
   /* Note we only warn for non-zero initializers.  */
   static union foo1 f1 = {0};
diff -rup orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-3.c egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-3.c
--- orig/egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-3.c	Thu Dec  7 18:21:09 2000
+++ egcc-CVS20020630/gcc/testsuite/gcc.dg/wtr-union-init-3.c	Sun Jun 30 21:34:59 2002
@@ -38,7 +38,7 @@ struct baz2
 };
 
 void
-testfunc (void)
+testfunc ()
 {
   /* Note we only warn for non-zero initializers.  Xfail on substructures. */
   static union foo f1 = {{0,0}}; /* { dg-bogus "traditional C rejects initialization of unions" "initialization of unions" { xfail *-*-* } } */



-----------------testcase gcc.dg/wtr-func-def-1.c---------------------
/* Test for -Wtraditional warnings on ISO C function definitions.
   Note, gcc should omit these warnings in system header files.
   Origin: Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 6/30/2002.  */
/* { dg-do compile } */
/* { dg-options "-Wtraditional" } */

/* Test some simple cases.  */

void f_void1 (void)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

void f_void2 ()
{
  return;
}

void f_int1 (int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

void f_int2 (f)
     int f;
{
  return;
}

/* Test that we don't ever warn about nested functions.  */

void f_int3 (int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  void f3a (void) { return; }
  void f3b () { return; }
  void f3c (int f) { return; }
  void f3d (f) int f; { return; }
  void f3e (const char *f, ...) { return; }
  return;
}

void f_int4 (int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  void f4a (void) { return; }
  void f4b () { return; }
  void f4c (int f) { return; }
  void f4d (f) int f; { return; }
  void f4e (const char *f, ...) { return; }
  auto f4f (void) { return 0; }
  return;
}

void f_int5 (f)
     int f;
{
  void f5a (void) { return; }
  void f5b () { return; }
  void f5c (int f) { return; }
  void f5d (f) int f; { return; }
  void f5e (const char *f, ...) { return; }
  return;
}

void f_int6 (f)
     int f;
{
  void f6a (void) { return; }
  void f6b () { return; }
  void f6c (int f) { return; }
  void f6d (f) int f; { return; }
  void f6e (const char *f, ...) { return; }
  auto f6f (void) { return 0; }
  return;
}

/* Test that prototypes are silently accepted and function definitions
   are still warned about.  */

extern void f_int_p1 (int);
void f_int_p1 (int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

extern void f_int_p2 (int f);
void f_int_p2 (int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

extern void f_int_p3 (int);
void f_int_p3 (f)
     int f;
{
  return;
}

extern void f_int_p4 (int f);
void f_int_p4 (f)
     int f;
{
  return;
}

extern void f_void_p1 ();
void f_void_p1 (void)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

extern void f_void_p2 (void);
void f_void_p2 (void)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

extern void f_blank_p1 ();
void f_blank_p1 ()
{
  return;
}

extern void f_blank_p2 (void);
void f_blank_p2 ()
{
  return;
}

/* Test some implicit int functions.  */

f_impl1()
{
  return 0;
}

f_impl2(void)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return 0;
}

f_impl3(int f)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return 0;
}

/* Test that we don't warn about stdarg functions.  */

f_stdarg1(const char *s, ...)
{
  return 0;
}

void f_stdarg2(const char *s, ...)
{
  return;
}

extern void f_stdarg3(const char *, ...);
void f_stdarg3(const char *s, ...)
{
  return;
}

/* Test handling function pointer parameters.  */

void f_fnptr1 (int f, int (*fp)(int));
void f_fnptr1 (int f, int (*fp)(int))
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return;
}

void f_fnptr2 (int f, int (*fp)(int));
void f_fnptr2 (f, fp)
     int f;
     int (*fp)(int);
{
  return;
}

/* Test for main.  */

int
main (int argc, char **argv)
{ /* { dg-warning "traditional C rejects ISO C style" } */
  return 0;
}

# 182 "sys-header.h" 3
/* We are in system headers now, no -Wtraditional warnings should issue.  */

void fsys1 (void)
{
  return;
}

void fsys2 (int f)
{
  return;
}

void fsys3 (const char *f, ...)
{
  return;
}



More information about the Gcc-patches mailing list