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]

Patch: enhance -Wconversion, and use some of it with -Wtraditional


In the past, I've run into portability problems on K&R systems because
when prototypes aren't present certain conversions don't take place.
The -Wconversion flag nicely detects these but also blathers about
1000s of signed/unsigned promotions which we don't care about.

The following patch activates those -Wconversion warnings with
-Wtraditional that useful IMHO.  E.g. float<->int or width changes,
but not signed<->unsigned.

While examining the general -Wconversion code, I noticed it detects
float<->complex conversions, but not int<->complex.  I fixed that too.

Bootstrapped on the trunk on solaris2.7.  Ok to install?

		Thanks,
		--Kaveh

PS: I'd also like to install this on the 3.0 branch to keep the
-Wtraditional behavior identical on both.  The changes are very
localized and simple so I don't think its risky.  I'll rebootstrap the
patch there if approved.


2001-04-09  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* c-typeck.c (convert_arguments): -Wtraditional now activates
	-Wconversion warnings, except for changes in signed-ness.
	Detect complex<->int & int<->complex conversions as well.

	* invoke.texi (-Wtraditional): Document it.

testsuite:
	* gcc.dg/wtr-conversion-1.c: New testcase.

diff -rup orig/egcs-CVS20010407/gcc/c-typeck.c egcs-CVS20010407/gcc/c-typeck.c
--- orig/egcs-CVS20010407/gcc/c-typeck.c	Tue Mar 27 07:41:28 2001
+++ egcs-CVS20010407/gcc/c-typeck.c	Mon Apr  9 17:17:08 2001
@@ -1676,19 +1676,25 @@ convert_arguments (typelist, values, nam
 	    {
 	      /* Optionally warn about conversions that
 		 differ from the default conversions.  */
-	      if (warn_conversion)
+	      if (warn_conversion || warn_traditional)
 		{
 		  int formal_prec = TYPE_PRECISION (type);
 
 		  if (INTEGRAL_TYPE_P (type)
 		      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
 		    warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+		  if (INTEGRAL_TYPE_P (type)
+		      && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
+		    warn_for_assignment ("%s as integer rather than complex due to prototype", (char *) 0, name, parmnum + 1);
 		  else if (TREE_CODE (type) == COMPLEX_TYPE
 			   && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
 		    warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
 		  else if (TREE_CODE (type) == REAL_TYPE
 			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
 		    warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
+		  else if (TREE_CODE (type) == COMPLEX_TYPE
+			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
+		    warn_for_assignment ("%s as complex rather than integer due to prototype", (char *) 0, name, parmnum + 1);
 		  else if (TREE_CODE (type) == REAL_TYPE
 			   && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
 		    warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
@@ -1749,10 +1755,15 @@ convert_arguments (typelist, values, nam
 		      else if (TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type)
 			       && TREE_UNSIGNED (TREE_TYPE (val)))
 			;
-		      else if (TREE_UNSIGNED (type))
-			warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
-		      else
-			warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
+		      /* These warnings are only activated with
+                         -Wconversion, not with -Wtraditional.  */
+		      else if (warn_conversion)
+		        {
+			  if (TREE_UNSIGNED (type))
+			    warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
+			  else
+			    warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
+			}
 		    }
 		}
 
diff -rup orig/egcs-CVS20010407/gcc/invoke.texi egcs-CVS20010407/gcc/invoke.texi
--- orig/egcs-CVS20010407/gcc/invoke.texi	Thu Mar 22 07:42:30 2001
+++ egcs-CVS20010407/gcc/invoke.texi	Mon Apr  9 16:19:41 2001
@@ -2122,6 +2122,11 @@ omitted.  This is done under the assumpt
 user code appears conditioned on e.g. @code{__STDC__} to avoid missing
 initializer warnings and relies on default initialization to zero in the
 traditional C case.
+
+@item
+Conversions by prototypes.  This is similar to @samp{-Wconversion} in
+that it warns about width changes and fixed/floating point conversions,
+however it does not warn about changes in signedness.
 @end itemize
 
 @item -Wundef
diff -rup orig/egcs-CVS20010407/gcc/testsuite/gcc.dg/wtr-conversion-1.c egcs-CVS20010407/gcc/testsuite/gcc.dg/wtr-conversion-1.c
--- orig/egcs-CVS20010407/gcc/testsuite/gcc.dg/wtr-conversion-1.c	Mon Apr  9 17:26:34 2001
+++ egcs-CVS20010407/gcc/testsuite/gcc.dg/wtr-conversion-1.c	Mon Apr  9 17:24:15 2001
@@ -0,0 +1,88 @@
+/* Test for -Wtraditional warnings on conversions by prototypes.
+   Note, gcc should omit these warnings in system header files.
+   By Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 4/09/2001.  */
+/* { dg-do compile } */
+/* { dg-options "-Wtraditional" } */
+
+extern void foo_c (char);
+extern void foo_ll (long long);
+extern void foo_f (float);
+extern void foo_ld (long double);
+extern void foo_cd (__complex__ double);
+
+extern char c;
+extern long long ll;
+extern float f;
+extern long double ld;
+extern __complex__ double cd;
+
+void
+testfunc1 (void)
+{
+  foo_c (c); /* { dg-warning "with different width" "prototype conversion warning" } */
+  foo_c (ll); /* { dg-warning "with different width" "prototype conversion warning" } */
+  foo_c (f); /* { dg-warning "as integer rather than floating" "prototype conversion warning" } */
+  foo_c (ld); /* { dg-warning "as integer rather than floating" "prototype conversion warning" } */
+  foo_c (cd); /* { dg-warning "as integer rather than complex" "prototype conversion warning" } */
+
+  foo_ll (c); /* { dg-warning "with different width" "prototype conversion warning" } */
+  foo_ll (ll);
+  foo_ll (f); /* { dg-warning "as integer rather than floating" "prototype conversion warning" } */
+  foo_ll (ld); /* { dg-warning "as integer rather than floating" "prototype conversion warning" } */
+  foo_ll (cd); /* { dg-warning "as integer rather than complex" "prototype conversion warning" } */
+
+  foo_f (c); /* { dg-warning "as floating rather than integer" "prototype conversion warning" } */
+  foo_f (ll); /* { dg-warning "as floating rather than integer" "prototype conversion warning" } */
+  foo_f (f); /* { dg-warning "as `float' rather than `double'" "prototype conversion warning" } */
+  foo_f (ld); /* { dg-warning "as `float' rather than `double'" "prototype conversion warning" } */
+  foo_f (cd); /* { dg-warning "as floating rather than complex" "prototype conversion warning" } */
+
+  foo_ld (c); /* { dg-warning "as floating rather than integer" "prototype conversion warning" } */
+  foo_ld (ll); /* { dg-warning "as floating rather than integer" "prototype conversion warning" } */
+  foo_ld (f);
+  foo_ld (ld);
+  foo_ld (cd); /* { dg-warning "as floating rather than complex" "prototype conversion warning" } */
+
+  foo_cd (c); /* { dg-warning "as complex rather than integer" "prototype conversion warning" } */
+  foo_cd (ll); /* { dg-warning "as complex rather than integer" "prototype conversion warning" } */
+  foo_cd (f); /* { dg-warning "as complex rather than floating" "prototype conversion warning" } */
+  foo_cd (ld); /* { dg-warning "as complex rather than floating" "prototype conversion warning" } */
+  foo_cd (cd);
+}
+  
+# 54 "sys-header.h" 3
+/* We are in system headers now, no -Wtraditional warnings should issue.  */
+
+void
+testfunc2 (void)
+{
+  foo_c (c);
+  foo_c (ll);
+  foo_c (f);
+  foo_c (ld);
+  foo_c (cd);
+
+  foo_ll (c);
+  foo_ll (ll);
+  foo_ll (f);
+  foo_ll (ld);
+  foo_ll (cd);
+
+  foo_f (c);
+  foo_f (ll);
+  foo_f (f);
+  foo_f (ld);
+  foo_f (cd);
+
+  foo_ld (c);
+  foo_ld (ll);
+  foo_ld (f);
+  foo_ld (ld);
+  foo_ld (cd);
+
+  foo_cd (c);
+  foo_cd (ll);
+  foo_cd (f);
+  foo_cd (ld);
+  foo_cd (cd);
+}


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