This is the mail archive of the gcc@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]

[PATCH] Wcoercion: removed overflow check


This patch is an improved version over the one proposed in
http://gcc.gnu.org/ml/gcc-patches/2006-07/msg00098.html
It doesn't introduce any features. The main difference is the removal
of TREE_CONSTANT_OVERFLOW check from real_isinteger function,
following the new policy about not handling overflow in the front end.
This patch also fixes some minor issues with whitespace and comments.
Thanks to Roger Sayle for his helpful comments.

Bootstrapped and tested in trunk revision 115112.

As the original one, it is composed by three patches:

wcoercion-1of3-split.patch : splits current functionality of
Wconversion in two different options and it modifies testcases
accordingly. (this one hasn't changed at all, it is included here for
completeness)
wcoercion-2of3-real_isinteger-2.patch : adds a new function which
detects when a real value can be exactly represented as an integer.
wcoercion-3of3-coercion_warning-2.patch : adds the new functionality and
testcases.
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/c-common.c wcoercion/gcc/c-common.c
--- pristine/gcc/c-common.c	2006-07-01 13:37:45.000000000 +0100
+++ wcoercion/gcc/c-common.c	2006-07-01 13:40:44.000000000 +0100
@@ -949,7 +949,7 @@ overflow_warning (tree value)
 }
 
 /* Print a warning if a large constant is truncated to unsigned,
-   or if -Wconversion is used and a constant < 0 is converted to unsigned.
+   or if -Wcoercion is used and a constant < 0 is converted to unsigned.
    Invoke this function on every expression that might be implicitly
    converted to an unsigned type.  */
 
@@ -969,7 +969,7 @@ unsigned_conversion_warning (tree result
 	warning (OPT_Woverflow,
 		 "large integer implicitly truncated to unsigned type");
       else
-	warning (OPT_Wconversion,
+	warning (OPT_Wcoercion,
 		 "negative integer implicitly converted to unsigned type");
     }
 }
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/c.opt wcoercion/gcc/c.opt
--- pristine/gcc/c.opt	2006-06-04 09:53:03.000000000 +0100
+++ wcoercion/gcc/c.opt	2006-06-25 20:33:21.000000000 +0100
@@ -141,6 +141,10 @@ Wchar-subscripts
 C ObjC C++ ObjC++ Var(warn_char_subscripts)
 Warn about subscripts whose type is \"char\"
 
+Wcoercion
+C ObjC C++ ObjC++ Var(warn_coercion)
+Warn for implicit type conversions that may change a value
+
 Wcomment
 C ObjC C++ ObjC++
 Warn about possibly nested block comments, and C++ comments spanning more than one physical line
@@ -150,8 +154,12 @@ C ObjC C++ ObjC++
 Synonym for -Wcomment
 
 Wconversion
-C ObjC C++ ObjC++ Var(warn_conversion)
-Warn about possibly confusing type conversions
+C++ ObjC++ Var(warn_conversion)
+Undocumented
+
+Wtraditional-conversion
+C ObjC Var(warn_traditional_conversion)
+Warn of prototypes causing type conversions different from what would happen in the absence of prototype
 
 Wctor-dtor-privacy
 C++ ObjC++ Var(warn_ctor_dtor_privacy)
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/c-typeck.c wcoercion/gcc/c-typeck.c
--- pristine/gcc/c-typeck.c	2006-07-01 13:38:05.000000000 +0100
+++ wcoercion/gcc/c-typeck.c	2006-07-01 13:40:43.000000000 +0100
@@ -2389,7 +2389,7 @@ convert_arguments (tree typelist, tree v
 	    {
 	      /* Optionally warn about conversions that
 		 differ from the default conversions.  */
-	      if (warn_conversion || warn_traditional)
+	      if (warn_traditional_conversion || warn_traditional)
 		{
 		  unsigned int formal_prec = TYPE_PRECISION (type);
 
@@ -2465,8 +2465,8 @@ convert_arguments (tree typelist, tree v
 		    }
 		  /* Detect integer changing in width or signedness.
 		     These warnings are only activated with
-		     -Wconversion, not with -Wtraditional.  */
-		  else if (warn_conversion && INTEGRAL_TYPE_P (type)
+		     -Wtraditional-conversion, not with -Wtraditional.  */
+		  else if (warn_traditional_conversion && INTEGRAL_TYPE_P (type)
 			   && INTEGRAL_TYPE_P (TREE_TYPE (val)))
 		    {
 		      tree would_have_been = default_conversion (val);
@@ -2479,7 +2479,7 @@ convert_arguments (tree typelist, tree v
 			   and the actual arg is that enum type.  */
 			;
 		      else if (formal_prec != TYPE_PRECISION (type1))
-			warning (OPT_Wconversion, "passing argument %d of %qE "
+			warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
 				 "with different width due to prototype",
 				 argnum, rname);
 		      else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
@@ -2502,11 +2502,11 @@ convert_arguments (tree typelist, tree v
 			       && TYPE_UNSIGNED (TREE_TYPE (val)))
 			;
 		      else if (TYPE_UNSIGNED (type))
-			warning (OPT_Wconversion, "passing argument %d of %qE "
+			warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
 				 "as unsigned due to prototype",
 				 argnum, rname);
 		      else
-			warning (OPT_Wconversion, "passing argument %d of %qE "
+			warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
 				 "as signed due to prototype", argnum, rname);
 		    }
 		}
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/doc/invoke.texi wcoercion/gcc/doc/invoke.texi
--- pristine/gcc/doc/invoke.texi	2006-07-01 13:38:33.000000000 +0100
+++ wcoercion/gcc/doc/invoke.texi	2006-07-01 13:40:44.000000000 +0100
@@ -223,8 +223,8 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Warning Options,,Options to Request or Suppress Warnings}.
 @gccoptlist{-fsyntax-only  -pedantic  -pedantic-errors @gol
 -w  -Wextra  -Wall  -Waggregate-return -Walways-true -Wno-attributes @gol
--Wc++-compat -Wcast-align  -Wcast-qual  -Wchar-subscripts  -Wcomment @gol
--Wconversion  -Wno-deprecated-declarations @gol
+-Wc++-compat -Wcast-align  -Wcast-qual  -Wchar-subscripts -Wcoercion @gol
+-Wcomment -Wtraditional-conversion  -Wno-deprecated-declarations @gol
 -Wdisabled-optimization  -Wno-div-by-zero  -Wno-endif-labels @gol
 -Werror  -Werror-* -Werror-implicit-function-declaration @gol
 -Wfatal-errors  -Wfloat-equal  -Wformat  -Wformat=2 @gol
@@ -3018,7 +3018,7 @@ traditional C case.
 Conversions by prototypes between fixed/floating point values and vice
 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}.
+conversion warnings, for the full set use @option{-Wtraditional-conversion}.
 
 @item
 Use of ISO C style function definitions.  This warning intentionally is
@@ -3106,18 +3106,23 @@ only if you have been very careful about
 declarations and prototypes.  Otherwise, it will just be a nuisance;
 this is why we did not make @option{-Wall} request these warnings.
 
-@item -Wconversion
-@opindex Wconversion
+@item -Wtraditional-conversion
+@opindex Wtraditional-conversion
 Warn if a prototype causes a type conversion that is different from what
 would happen to the same argument in the absence of a prototype.  This
 includes conversions of fixed point to floating and vice versa, and
 conversions changing the width or signedness of a fixed point argument
 except when the same as the default promotion.
 
-Also, warn if a negative integer constant expression is implicitly
-converted to an unsigned type.  For example, warn about the assignment
-@code{x = -1} if @code{x} is unsigned.  But do not warn about explicit
-casts like @code{(unsigned) -1}.
+@item -Wcoercion
+@opindex Wcoercion
+Warn for implicit conversions that may alter a value. This includes
+conversions caused by function prototypes like @code{abs(x)} when
+@code{x} is real and by assignments like
+@code{unsigned x = -1}. Do not warn about explicit casts like
+@code{abs((int)x)} and @code{x = (unsigned) -1}, or if the value is not
+changed by the conversion like @code{abs(2.0)}.
+
 
 @item -Wsign-compare
 @opindex Wsign-compare
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/doc/trouble.texi wcoercion/gcc/doc/trouble.texi
--- pristine/gcc/doc/trouble.texi	2006-06-11 18:02:27.000000000 +0100
+++ wcoercion/gcc/doc/trouble.texi	2006-06-11 18:58:00.000000000 +0100
@@ -985,10 +985,10 @@ you are removing prototypes that were ma
 the program worked before without any prototypes, it will work again
 without them.
 
-@opindex Wconversion
+@opindex Wtraditional-conversion
 You can find all the places where this problem might occur by compiling
-the program with the @option{-Wconversion} option.  It prints a warning
-whenever an argument is converted.
+the program with the @option{-Wtraditional-conversion} option.  It
+prints a warning whenever an argument is converted.
 
 @item
 Both conversion programs can be confused if there are macro calls in and
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/builtin-protos-1.c wcoercion/gcc/testsuite/gcc.dg/builtin-protos-1.c
--- pristine/gcc/testsuite/gcc.dg/builtin-protos-1.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/builtin-protos-1.c	2006-06-15 18:43:03.000000000 +0100
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options -Wconversion } */
+/* { dg-options -Wtraditional-conversion } */
 
 int
 test_s (signed int x)
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/dfp/Wconversion-2.c wcoercion/gcc/testsuite/gcc.dg/dfp/Wconversion-2.c
--- pristine/gcc/testsuite/gcc.dg/dfp/Wconversion-2.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/dfp/Wconversion-2.c	2006-06-15 18:00:23.000000000 +0100
@@ -1,6 +1,6 @@
-/* Test messages for -Wconversion (based on gcc.dg/Wconversion-2.c).  */
+/* Test messages for -Wtraditional-conversion (based on gcc.dg/Wconversion-2.c).  */
 /* { dg-do compile } */
-/* { dg-options "-std=gnu99 -Wconversion" } */
+/* { dg-options "-std=gnu99 -Wtraditional-conversion" } */
 
 void fsi(signed int);
 void fd32(_Decimal32);
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/overflow-warn-1.c wcoercion/gcc/testsuite/gcc.dg/overflow-warn-1.c
--- pristine/gcc/testsuite/gcc.dg/overflow-warn-1.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/overflow-warn-1.c	2006-06-15 18:18:37.000000000 +0100
@@ -102,7 +102,7 @@ void
 h2i (int x)
 {
   /* For some reason, we only give certain warnings for implicit
-     conversions among values of the same precision with -Wconversion,
+     conversions among values of the same precision with -Wcoercion,
      while we don't give others at all.  */
   fsi ((unsigned)INT_MAX + 1);
   si = (unsigned)INT_MAX + 1;
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/overflow-warn-2.c wcoercion/gcc/testsuite/gcc.dg/overflow-warn-2.c
--- pristine/gcc/testsuite/gcc.dg/overflow-warn-2.c	2006-06-04 09:53:03.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/overflow-warn-2.c	2006-06-15 18:44:28.000000000 +0100
@@ -1,7 +1,7 @@
-/* Test for diagnostics for constant overflow.  Test with -Wconversion.  */
+/* Test for diagnostics for constant overflow.  Test with -Wtraditional-conversion.  */
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
 /* { dg-do compile } */
-/* { dg-options "-std=c99 -Wconversion" } */
+/* { dg-options "-std=c99 -Wtraditional-conversion" } */
 
 #include <limits.h>
 
@@ -82,23 +82,23 @@ void
 h2 (void)
 {
   fsc (SCHAR_MAX + 1);
-  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wconversion" { target *-*-* } 84 } */
+  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 84 } */
   fsc (SCHAR_MIN - 1); /* { dg-warning "warning: overflow in implicit constant conversion" } */
-  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wconversion" { target *-*-* } 86 } */
+  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 86 } */
   fsc (UCHAR_MAX);
-  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wconversion" { target *-*-* } 88 } */
+  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 88 } */
   fsc (UCHAR_MAX + 1); /* { dg-warning "warning: overflow in implicit constant conversion" } */
-  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wconversion" { target *-*-* } 90 } */
-  fuc (-1); /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wconversion" { target *-*-* } 92 } */
+  /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 90 } */
+  fuc (-1);
+  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 92 } */
   fuc (UCHAR_MAX + 1); /* { dg-warning "warning: large integer implicitly truncated to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wconversion" { target *-*-* } 94 } */
-  fuc (SCHAR_MIN); /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wconversion" { target *-*-* } 96 } */
+  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 94 } */
+  fuc (SCHAR_MIN);
+  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 96 } */
   fuc (SCHAR_MIN - 1); /* { dg-warning "warning: large integer implicitly truncated to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wconversion" { target *-*-* } 98 } */
+  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 98 } */
   fuc (-UCHAR_MAX); /* { dg-warning "warning: large integer implicitly truncated to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wconversion" { target *-*-* } 100 } */
+  /* { dg-warning "warning: passing argument 1 of 'fuc' with different width due to prototype" "-Wtraditional-conversion" { target *-*-* } 100 } */
 }
 
 void fui (unsigned int);
@@ -111,7 +111,7 @@ void
 h2i (int x)
 {
   /* For some reason, we only give certain warnings for implicit
-     conversions among values of the same precision with -Wconversion,
+     conversions among values of the same precision with -Wtraditional-conversion,
      while we don't give others at all.  */
   fsi ((unsigned)INT_MAX + 1); /* { dg-warning "warning: passing argument 1 of 'fsi' as signed due to prototype" } */
   si = (unsigned)INT_MAX + 1;
@@ -121,12 +121,12 @@ h2i (int x)
   si = x ? (unsigned)INT_MAX + 2 : 1;
   fsi (UINT_MAX); /* { dg-warning "warning: passing argument 1 of 'fsi' as signed due to prototype" } */
   si = UINT_MAX;
-  fui (-1); /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fui' as unsigned due to prototype" "-Wconversion" { target *-*-* } 124 } */
-  ui = -1; /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  ui = x ? -1 : 1U; /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  fui (INT_MIN); /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  /* { dg-warning "warning: passing argument 1 of 'fui' as unsigned due to prototype" "-Wconversion" { target *-*-* } 128 } */
-  ui = INT_MIN; /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
-  ui = x ? INT_MIN : 1U; /* { dg-warning "warning: negative integer implicitly converted to unsigned type" } */
+  fui (-1);
+  /* { dg-warning "warning: passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 124 } */
+  ui = -1;
+  ui = x ? -1 : 1U;
+  fui (INT_MIN);
+  /* { dg-warning "warning: passing argument 1 of 'fui' as unsigned due to prototype" "-Wtraditional-conversion" { target *-*-* } 128 } */
+  ui = INT_MIN;
+  ui = x ? INT_MIN : 1U;
 }
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/overflow-warn-3.c wcoercion/gcc/testsuite/gcc.dg/overflow-warn-3.c
--- pristine/gcc/testsuite/gcc.dg/overflow-warn-3.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/overflow-warn-3.c	2006-06-15 18:20:16.000000000 +0100
@@ -109,7 +109,7 @@ void
 h2i (int x)
 {
   /* For some reason, we only give certain warnings for implicit
-     conversions among values of the same precision with -Wconversion,
+     conversions among values of the same precision with -Wcoercion,
      while we don't give others at all.  */
   fsi ((unsigned)INT_MAX + 1);
   si = (unsigned)INT_MAX + 1;
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/overflow-warn-4.c wcoercion/gcc/testsuite/gcc.dg/overflow-warn-4.c
--- pristine/gcc/testsuite/gcc.dg/overflow-warn-4.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/overflow-warn-4.c	2006-06-15 18:45:18.000000000 +0100
@@ -109,7 +109,7 @@ void
 h2i (int x)
 {
   /* For some reason, we only give certain warnings for implicit
-     conversions among values of the same precision with -Wconversion,
+     conversions among values of the same precision with -Wcoercion
      while we don't give others at all.  */
   fsi ((unsigned)INT_MAX + 1);
   si = (unsigned)INT_MAX + 1;
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wcoercion-negative-constants.c wcoercion/gcc/testsuite/gcc.dg/Wcoercion-negative-constants.c
--- pristine/gcc/testsuite/gcc.dg/Wcoercion-negative-constants.c	1970-01-01 01:00:00.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wcoercion-negative-constants.c	2006-06-25 00:32:47.000000000 +0100
@@ -0,0 +1,59 @@
+/* Test for diagnostics for negative constants coerced to unsigned types
+   These tests come from gcc/testsuite/gcc.dg/overflow-warn-2.c
+   Origin: Manuel Lopez-Ibanez <lopezibanez@gmail.com> */
+
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -Wcoercion" } */
+
+#include <limits.h>
+
+void fuc (unsigned char);
+
+void hc (int x)
+{
+  unsigned char uc;
+
+  fuc (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  uc = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  uc = x ? 1U : -1; /* { dg-warning "coercion to 'unsigned char' from 'unsigned int' may alter its value" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 18 } */
+  uc = x ? SCHAR_MIN : 1U; /* { dg-warning "coercion to 'unsigned char' from 'unsigned int' may alter its value" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" { target *-*-* } 20 } */
+  uc = '\xa0'; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+  fuc('A');
+  uc = 'A';
+
+  uc = x ? 1 : -1; /* { dg-warning "coercion to 'unsigned char' from 'int' may alter its value" } */
+  /* { dg-warning "negative integer may be implicitly converted to unsigned type" "" {xfail *-*-*} 27 } */
+  uc = x ? SCHAR_MIN : 1; /* { dg-warning "coercion to 'unsigned char' from 'int' may alter its value" } */
+  /* { dg-warning "negative integer may be implicitly converted to unsigned type" "" {xfail *-*-*} 29 } */
+
+}
+
+unsigned fui (unsigned int ui);
+
+void hi (int x)
+{
+  unsigned ui;
+
+  fui (-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = x ? 1U : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = x ? INT_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = ui ? SCHAR_MIN : 1U; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = 1U * -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  ui = ui + INT_MIN; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+  ui = -1 * (1 * -1);
+  ui = (unsigned) -1;
+
+  ui = x ? 1 : -1; /* { dg-warning "coercion to 'unsigned int' from 'int' may alter its value" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" {xfail *-*-*} 51 } */
+  ui = x ? INT_MIN : 1; /* { dg-warning "coercion to 'unsigned int' from 'int' may alter its value" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" {xfail *-*-*} 53 } */
+  ui = ui ? SCHAR_MIN : 1; /* { dg-warning "coercion to 'unsigned int' from 'int' may alter its value" } */
+  /* { dg-warning "negative integer implicitly converted to unsigned type" "" {xfail *-*-*} 55 } */
+}
+
+unsigned fui(unsigned a) { return a + -1; } /* { dg-warning "negative integer implicitly converted to unsigned type" } */
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wconversion-2.c wcoercion/gcc/testsuite/gcc.dg/Wconversion-2.c
--- pristine/gcc/testsuite/gcc.dg/Wconversion-2.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wconversion-2.c	2006-06-15 18:23:11.000000000 +0100
@@ -1,8 +1,8 @@
-/* Test messages for -Wconversion, including that they are not
+/* Test messages for -Wtraditional-conversion, including that they are not
    pedwarns.  */
 /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
 /* { dg-do compile } */
-/* { dg-options "-std=c99 -pedantic-errors -Wconversion" } */
+/* { dg-options "-std=c99 -pedantic-errors -Wtraditional-conversion" } */
 
 void fsc(signed char);
 void fsi(signed int);
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wconversion-3.c wcoercion/gcc/testsuite/gcc.dg/Wconversion-3.c
--- pristine/gcc/testsuite/gcc.dg/Wconversion-3.c	2006-06-04 09:53:03.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wconversion-3.c	2006-06-04 01:01:35.000000000 +0100
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -Wconversion" } */
+/* { dg-options "-O2 -Wcoercion" } */
 
 unsigned f(unsigned a) { return a + -1; }  /* { dg-warning "negative" } */
 
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wconversion.c wcoercion/gcc/testsuite/gcc.dg/Wconversion.c
--- pristine/gcc/testsuite/gcc.dg/Wconversion.c	2006-06-15 19:07:10.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wconversion.c	2006-06-15 22:12:45.000000000 +0100
@@ -5,7 +5,7 @@
    not used in the appropriate place in the warning code.  */
 
 /* { dg-do compile } */
-/* { dg-options -Wconversion } */
+/* { dg-options -Wtraditional-conversion } */
 
 typedef enum { a } __attribute__((packed)) t;
 void f(t x) {}
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='*~' pristine/gcc/testsuite/g++.old-deja/g++.other/warn4.C wcoercion/gcc/testsuite/g++.old-deja/g++.other/warn4.C
--- pristine/gcc/testsuite/g++.old-deja/g++.other/warn4.C	2006-06-07 00:57:15.000000000 +0100
+++ wcoercion/gcc/testsuite/g++.old-deja/g++.other/warn4.C	2006-06-07 00:47:13.000000000 +0100
@@ -1,5 +1,5 @@
 // { dg-do assemble  }
-// { dg-options "-Wconversion" }
+// { dg-options "-Wcoercion" }
 
 // Copyright (C) 1999 Free Software Foundation, Inc.
 // Contributed by Nathan Sidwell 21 Nov 1999 <nathan@acm.org>
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/builtins.c wcoercion/gcc/builtins.c
--- pristine/gcc/builtins.c	2006-06-16 23:13:57.000000000 +0100
+++ wcoercion/gcc/builtins.c	2006-07-09 20:32:47.000000000 +0100
@@ -6654,15 +6654,7 @@ integer_valued_real_p (tree t)
 	     && integer_valued_real_p (TREE_OPERAND (t, 2));
 
     case REAL_CST:
-      if (! TREE_CONSTANT_OVERFLOW (t))
-      {
-	REAL_VALUE_TYPE c, cint;
-
-	c = TREE_REAL_CST (t);
-	real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
-	return real_identical (&c, &cint);
-      }
-      break;
+      return real_isinteger (TREE_REAL_CST (t), TYPE_MODE (TREE_TYPE (t)));
 
     case NOP_EXPR:
       {
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/real.c wcoercion/gcc/real.c
--- pristine/gcc/real.c	2006-06-12 22:37:50.000000000 +0100
+++ wcoercion/gcc/real.c	2006-07-09 20:32:47.000000000 +0100
@@ -4922,3 +4922,13 @@ real_copysign (REAL_VALUE_TYPE *r, const
   r->sign = x->sign;
 }
 
+/* Check whether the real constant value given is an integer.  */
+
+bool
+real_isinteger (const REAL_VALUE_TYPE c, enum machine_mode mode)
+{
+  REAL_VALUE_TYPE cint;
+
+  real_trunc (&cint, mode, &c);
+  return real_identical (&c, &cint);
+}
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/real.h wcoercion/gcc/real.h
--- pristine/gcc/real.h	2006-06-12 22:37:50.000000000 +0100
+++ wcoercion/gcc/real.h	2006-07-09 20:47:47.000000000 +0100
@@ -425,4 +425,7 @@ extern void real_round (REAL_VALUE_TYPE 
 /* Set the sign of R to the sign of X.  */
 extern void real_copysign (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
 
+/* Check whether the real constant value given is an integer.  */
+extern bool real_isinteger (const REAL_VALUE_TYPE c, enum machine_mode mode);
+
 #endif /* ! GCC_REAL_H */
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/c-common.c wcoercion/gcc/c-common.c
--- pristine/gcc/c-common.c	2006-07-01 13:37:45.000000000 +0100
+++ wcoercion/gcc/c-common.c	2006-07-09 20:47:07.000000000 +0100
@@ -1067,6 +1067,109 @@ vector_types_convertible_p (tree t1, tre
 		== INTEGRAL_TYPE_P (TREE_TYPE (t2)));
 }
 
+/* Warns if the conversion of EXPR to TYPE may alter a value.
+   This function is called from convert_and_check().  */
+
+void
+coercion_warning (tree type, tree expr)
+{
+  bool give_warning = false;
+
+  unsigned int formal_prec = TYPE_PRECISION (type);
+
+  if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
+    {
+      /* Warn for real constant that is not an exact integer coerced
+         to integer type.  */
+      if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+          && TREE_CODE (type) == INTEGER_TYPE
+          && !real_isinteger (TREE_REAL_CST (expr), TYPE_MODE (TREE_TYPE (expr))))
+        give_warning = true;
+
+      /* Warn for an integer constant that does not fit into integer
+         type. However, warnings for negative constants coerced to
+         unsigned types are detected by unsigned_conversion_warning.  */
+      else if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
+               && TREE_CODE (type) == INTEGER_TYPE
+               && !int_fits_type_p (expr, type)
+               && TYPE_UNSIGNED (TREE_TYPE (expr)) == TYPE_UNSIGNED (type))
+        give_warning = true;
+
+      else if (TREE_CODE (type) == REAL_TYPE)
+        {
+          if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE)
+            {
+              REAL_VALUE_TYPE a = real_value_from_int_cst (0, expr);
+              if (!exact_real_truncate (TYPE_MODE (type), &a))
+                give_warning = true;
+            }
+          else if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+                   && formal_prec < TYPE_PRECISION (TREE_TYPE (expr)))
+            {
+              REAL_VALUE_TYPE a = TREE_REAL_CST (expr);
+              if (!exact_real_truncate (TYPE_MODE (type), &a))
+                give_warning = true;
+            }
+        }
+
+      if (give_warning)
+        warning (OPT_Wcoercion,
+                 "coercion as %qT alters %qT constant value",
+                 type, TREE_TYPE (expr));
+    }
+  else /* 'expr' is not a constant.  */
+    {
+      /* Warn for real types coerced to integer types.  */
+      if (TREE_CODE (type) == INTEGER_TYPE
+          && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
+        give_warning = true;
+
+      /* Warn for integer types coerced to real types if and only if
+         all the range of values of the integer type cannot be
+         represented by the real type.  */
+      else if (TREE_CODE (type) == REAL_TYPE
+               && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE)
+        {
+          tree type_low_bound = TYPE_MIN_VALUE (TREE_TYPE (expr));
+          tree type_high_bound = TYPE_MAX_VALUE (TREE_TYPE (expr));
+          REAL_VALUE_TYPE real_low_bound = real_value_from_int_cst (0, type_low_bound);
+          REAL_VALUE_TYPE real_high_bound = real_value_from_int_cst (0, type_high_bound);
+
+          if (!exact_real_truncate (TYPE_MODE (type), &real_low_bound)
+              || !exact_real_truncate (TYPE_MODE (type), &real_high_bound))
+            give_warning = true;
+        }
+
+      /* Warn for real types coerced to smaller real types.  */
+      else if (TREE_CODE (type) == REAL_TYPE
+               && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
+               && formal_prec < TYPE_PRECISION (TREE_TYPE (expr)))
+        give_warning = true;
+
+
+      else if (TREE_CODE  (type) == INTEGER_TYPE
+               && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE)
+        {
+          /* Warn for integer types coerced to smaller integer types.  */
+          if (formal_prec < TYPE_PRECISION (TREE_TYPE (expr))
+              /* When they are the same width but different signedness,
+                 then the value may change.  */
+              || (formal_prec == TYPE_PRECISION (TREE_TYPE (expr))
+                  && TYPE_UNSIGNED (TREE_TYPE (expr)) != TYPE_UNSIGNED (type))
+              /* Even when coerced to a bigger type, if the type is
+                 unsigned but expr is signed, then negative values
+                 will be changed.  */
+              || (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (TREE_TYPE (expr))))
+            give_warning = true;
+        }
+
+      if (give_warning)
+        warning (OPT_Wcoercion,
+                 "coercion to %qT from %qT may alter its value",
+                 type, TREE_TYPE (expr));
+    }
+}
+
 /* Convert EXPR to TYPE, warning about conversion problems with constants.
    Invoke this function on every expression that is converted implicitly,
    i.e. because of language rules and not because of an explicit cast.  */
@@ -1074,7 +1177,12 @@ vector_types_convertible_p (tree t1, tre
 tree
 convert_and_check (tree type, tree expr)
 {
-  tree t = convert (type, expr);
+  tree t;
+
+  if (warn_coercion)
+    coercion_warning (type, expr);
+
+  t = convert (type, expr);
   if (TREE_CODE (t) == INTEGER_CST)
     {
       if (TREE_OVERFLOW (t))
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/c-common.h wcoercion/gcc/c-common.h
--- pristine/gcc/c-common.h	2006-06-21 23:32:46.000000000 +0100
+++ wcoercion/gcc/c-common.h	2006-07-09 20:32:36.000000000 +0100
@@ -656,6 +656,7 @@ struct varray_head_tag;
 extern void constant_expression_warning (tree);
 extern void strict_aliasing_warning(tree, tree, tree);
 extern void empty_body_warning (tree, tree);
+extern void coercion_warning (tree type, tree expr);
 extern tree convert_and_check (tree, tree);
 extern void overflow_warning (tree);
 extern bool c_determine_visibility (tree);
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wcoercion-assignments.c wcoercion/gcc/testsuite/gcc.dg/Wcoercion-assignments.c
--- pristine/gcc/testsuite/gcc.dg/Wcoercion-assignments.c	1970-01-01 01:00:00.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wcoercion-assignments.c	2006-07-09 20:32:36.000000000 +0100
@@ -0,0 +1,87 @@
+/* Test for diagnostics for Wcoercion in assignments.
+   Origin: Manuel Lopez-Ibanez <lopezibanez@gmail.com> */
+
+/* { dg-do compile }
+/* { dg-options "-fsigned-char -std=c99 -Wcoercion" } */
+
+#include <limits.h>
+#include <float.h>
+
+# define M_PI		3.14159265358979323846	/* pi */
+
+float  vfloat;
+double vdouble;
+long double vlongdouble;
+
+char   vchar;
+short int vshortint;
+int vint;
+long vlongint;
+long long vlonglong;
+
+void h(void)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  float  f = 3;
+  double d = 3;
+
+  vint = 3.1f; /* { dg-warning "coercion" } */
+  vint = 3.1; /* { dg-warning "coercion" } */
+  vfloat = INT_MAX; /* { dg-warning "coercion" } */
+  vfloat = DBL_MIN; /* { dg-warning "coercion" } */
+  vfloat = M_PI; /* { dg-warning "coercion" } */
+  vfloat = 3.1; /* { dg-warning "coercion" } */
+  vint = d; /* { dg-warning "coercion" } */
+  vfloat = d; /* { dg-warning "coercion" } */
+  vfloat = si; /* { dg-warning "coercion" } */
+  vfloat = ui; /* { dg-warning "coercion" } */
+  vfloat = 16777217; /* { dg-warning "coercion" } */
+
+  /* No warning */
+  vint = 3;
+  vint = 3.0f;
+  vint = 3.0;
+  vint = 16777217.0f;
+  vfloat = 3U;
+  vfloat = 3;
+  vfloat = INT_MIN;
+  vdouble = UINT_MAX;
+  vdouble = ui;
+  vfloat = 3.0;
+  vfloat = 3.1f;
+  vfloat = 0.25;
+  vfloat = f;
+  vdouble = d;
+  vdouble = f;
+  vdouble = 16777217;
+
+}
+
+
+unsigned char vuc;
+unsigned int vui;
+
+void h2(void)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  unsigned char uc = 3;
+  signed char   sc = 3;
+
+  vint = ui;/* { dg-warning "coercion" } */
+  vui = si; /* { dg-warning "coercion" } */
+  vui = sc; /* { dg-warning "coercion" } */
+  vui = -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  vui = '\xa0'; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  vuc = '\xa0'; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+  /* no warning */
+  vint = uc;
+  vui = uc;
+  vui = 'A';
+  vuc = 'A';
+  vint = 'A';
+  vchar = 'A';
+  vchar = '\xa0';
+}
diff -pEbaur --unidirectional-new-file --exclude='*svn*' --exclude='#*' --exclude='*~' pristine/gcc/testsuite/gcc.dg/Wcoercion-calls.c wcoercion/gcc/testsuite/gcc.dg/Wcoercion-calls.c
--- pristine/gcc/testsuite/gcc.dg/Wcoercion-calls.c	1970-01-01 01:00:00.000000000 +0100
+++ wcoercion/gcc/testsuite/gcc.dg/Wcoercion-calls.c	2006-07-09 20:32:36.000000000 +0100
@@ -0,0 +1,87 @@
+/* Test for diagnostics for Wcoercion when passing arguments.
+   Origin: Manuel Lopez-Ibanez <lopezibanez@gmail.com> */
+
+/* { dg-do compile }
+/* { dg-options "-fsigned-char -std=c99 -Wcoercion" } */
+
+#include <limits.h>
+#include <float.h>
+
+# define M_PI		3.14159265358979323846	/* pi */
+
+void fchar(char x);
+void ffloat(float x);
+void fdouble(double x);
+void flongdouble(long double x);
+
+void fshortint(short int x);
+void fint(int x);
+void flongint(long int x);
+void flonglong(long long x);
+
+void h(void)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  float  f = 3;
+  double d = 3;
+
+  fint(3.1f); /* { dg-warning "coercion" } */
+  fint(3.1); /* { dg-warning "coercion" } */
+  ffloat(INT_MAX); /* { dg-warning "coercion" } */
+  ffloat(DBL_MIN); /* { dg-warning "coercion" } */
+  ffloat(M_PI); /* { dg-warning "coercion" } */
+  ffloat(3.1); /* { dg-warning "coercion" } */
+  fint(d); /* { dg-warning "coercion" } */
+  ffloat(d); /* { dg-warning "coercion" } */
+  ffloat(si); /* { dg-warning "coercion" } */
+  ffloat(ui); /* { dg-warning "coercion" } */
+  ffloat(16777217); /* { dg-warning "coercion" } */
+
+
+  fint(3);
+  fint(3.0f);
+  fint(3.0);
+  fint(16777217.0f);
+  ffloat(3U);
+  ffloat(3);
+  ffloat(INT_MIN);
+  fdouble(UINT_MAX);
+  fdouble(ui);
+  ffloat(3.0);
+  ffloat(3.1f);
+  ffloat(0.25);
+  ffloat(f);
+  fdouble(d);
+  fdouble(f);
+  fdouble(16777217);
+
+}
+
+
+void fuc(unsigned char uc);
+void fui(unsigned int  ui);
+
+void h2(void)
+{
+  unsigned int ui = 3;
+  int   si = 3;
+  unsigned char uc = 3;
+  signed char   sc = 3;
+
+  fint(ui); /* { dg-warning "coercion" } */
+  fui(si);/* { dg-warning "coercion" } */
+  fui(sc); /* { dg-warning "coercion" } */
+  fui(-1); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  fui('\xa0'); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+  fuc('\xa0'); /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+
+
+  fint(uc);
+  fui(uc);
+  fui('A');
+  fuc('A');
+  fint('A');
+  fchar('A');
+  fchar('\xa0');
+}

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