PR 23572 warnings for out of range floating-point constants

Manuel López-Ibáñez lopezibanez@gmail.com
Wed Mar 14 18:43:00 GMT 2007


:ADDPATCH C:

At the moment, there is a warning if a floating-point constant is too
large to fit in the type's range. In such cases the constant is
converted to +inf or -inf. However, there is no warning if the
constant is too small and it is taken as 0. The following patch adds
such warning following the advice of Joseph Myers
[http://gcc.gnu.org/ml/gcc-patches/2007-01/msg01739.html], that is,
for overflow, emit a pedantic warning if infinities are not supported,
otherwise emit just a warning iff -Woverflow, while for underflow,
emit a warning iff -Woverflow.

The testcases are a bit weak. I am not sure how to check that the
target supports or doesn't support infinities. Do we have a
'check_effective_target_support_inf' ? How can I add one?

Cheers,

Manuel.

2007-03-14  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

  PR other/23572
  * c-lex.c (interpret_float): On overflow, emit pedantic warning if
infinities not supported, otherwise emit warning if -Woverflow. On
underflow, emit warning if -Woverflow.

testsuite/
  * gcc.dg/float-range-4.c: New.
  * gcc.dg/float-range-1.c: Update. Test for a warning.
  * gcc.dg/float-range-3.c: New.
  * gcc.dg/float-range-5.c: New.
-------------- next part --------------
Index: gcc/c-lex.c
===================================================================
--- gcc/c-lex.c	(revision 122755)
+++ gcc/c-lex.c	(working copy)
@@ -636,7 +636,7 @@ interpret_float (const cpp_token *token,
 {
   tree type;
   tree value;
-  REAL_VALUE_TYPE real;
+  REAL_VALUE_TYPE real, realvoidmode;
   char *copy;
   size_t copylen;
 
@@ -678,14 +678,24 @@ interpret_float (const cpp_token *token,
   copy[copylen] = '\0';
 
   real_from_string3 (&real, copy, TYPE_MODE (type));
+  real_from_string3 (&realvoidmode, copy, VOIDmode);
 
   /* Both C and C++ require a diagnostic for a floating constant
      outside the range of representable values of its type.  Since we
-     have __builtin_inf* to produce an infinity, it might now be
-     appropriate for this to be a mandatory pedwarn rather than
-     conditioned on -pedantic.  */
-  if (REAL_VALUE_ISINF (real) && pedantic)
-    pedwarn ("floating constant exceeds range of %qT", type);
+     have __builtin_inf* to produce an infinity, this is now a
+     mandatory pedwarn if the target does not support infinities.  */
+  if (REAL_VALUE_ISINF (real)) 
+    {
+      if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
+	pedwarn ("floating constant exceeds range of %qT", type);
+      else
+	warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
+    }
+
+  /* We also give a warning if the value underflows.  */
+  if (REAL_VALUES_IDENTICAL (real, dconst0) 
+      && !REAL_VALUES_IDENTICAL (realvoidmode, dconst0)) 
+    warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
 
   /* Create a node with determined type and value.  */
   value = build_real (type, real);
Index: gcc/testsuite/gcc.dg/float-range-4.c
===================================================================
--- gcc/testsuite/gcc.dg/float-range-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/float-range-4.c	(revision 0)
@@ -0,0 +1,34 @@
+/* PR 23572 : warnings for out of range floating-point constants.  */
+/* { dg-compile } */
+/* { dg-options "-Wno-overflow -std=c99" } */
+#include <math.h>
+
+void overflow(void)
+{
+  float f1 = 3.5E+38f;  
+  float f2 = -3.5E+38f; 
+  float f3 = FP_INFINITE;
+  float f4 = -FP_INFINITE;
+
+  double d1 = 1.9E+308; 
+  double d2 = -1.9E+308;
+  double d3 = FP_INFINITE;
+  double d4 = -FP_INFINITE;
+}
+
+void underflow(void)
+{
+  float f1 = 3.3E-46f;  
+  float f2 = -3.3E-46f; 
+  float f3 = 0;
+  float f4 = -0;
+  float f5 = 0.0;
+  float f6 = -0.0;
+
+  double d1 = 1.4E-325; 
+  double d2 = -1.4E-325;
+  double d3 = 0;
+  double d4 = -0;
+  double d5 = 0.0;
+  double d6 = -0.0;
+}
Index: gcc/testsuite/gcc.dg/float-range-1.c
===================================================================
--- gcc/testsuite/gcc.dg/float-range-1.c	(revision 122755)
+++ gcc/testsuite/gcc.dg/float-range-1.c	(working copy)
@@ -1,13 +1,14 @@
 /* Floating constants outside the range of their type should receive a
-   pedwarn, not a warning.  */
+   just a warning if the target supports infinities. Otherwise, a
+   pedwarn should be produced.  */
 /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
 /* { dg-do compile } */
-/* { dg-options "-ansi -pedantic-errors" } */
+/* { dg-options "-ansi -pedantic-errors -Woverflow" } */
 
 void
 f (void)
 {
-  float a = 1e+100000000f; /* { dg-error "error: floating constant exceeds range of 'float'" } */
-  double b = 1e+100000000; /* { dg-error "error: floating constant exceeds range of 'double'" } */
-  long double c = 1e+100000000l; /* { dg-error "error: floating constant exceeds range of 'long double'" } */
+  float a = 1e+100000000f; /* { dg-warning "warning: floating constant exceeds range of 'float'" "" } */
+  double b = 1e+100000000; /* { dg-warning "warning: floating constant exceeds range of 'double'" } */
+  long double c = 1e+100000000l; /* { dg-warning "warning: floating constant exceeds range of 'long double'" } */
 }
Index: gcc/testsuite/gcc.dg/float-range-3.c
===================================================================
--- gcc/testsuite/gcc.dg/float-range-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/float-range-3.c	(revision 0)
@@ -0,0 +1,34 @@
+/* PR 23572 : warnings for out of range floating-point constants.  */
+/* { dg-compile } */
+/* { dg-options "-std=c99" } */
+#include <math.h>
+
+void overflow(void)
+{
+  float f1 = 3.5E+38f;  /* { dg-warning "warning: floating constant exceeds range" } */
+  float f2 = -3.5E+38f; /* { dg-warning "warning: floating constant exceeds range" } */
+  float f3 = FP_INFINITE;
+  float f4 = -FP_INFINITE;
+
+  double d1 = 1.9E+308;  /* { dg-warning "warning: floating constant exceeds range" } */
+  double d2 = -1.9E+308; /* { dg-warning "warning: floating constant exceeds range" } */
+  double d3 = FP_INFINITE;
+  double d4 = -FP_INFINITE;
+}
+
+void underflow(void)
+{
+  float f1 = 3.3E-46f;  /* { dg-warning "warning: floating constant exceeds range" } */
+  float f2 = -3.3E-46f; /* { dg-warning "warning: floating constant exceeds range" } */
+  float f3 = 0;
+  float f4 = -0;
+  float f5 = 0.0;
+  float f6 = -0.0;
+
+  double d1 = 1.4E-325;  /* { dg-warning "warning: floating constant exceeds range" } */
+  double d2 = -1.4E-325; /* { dg-warning "warning: floating constant exceeds range" } */
+  double d3 = 0;
+  double d4 = -0;
+  double d5 = 0.0;
+  double d6 = -0.0;
+}
Index: gcc/testsuite/gcc.dg/float-range-5.c
===================================================================
--- gcc/testsuite/gcc.dg/float-range-5.c	(revision 0)
+++ gcc/testsuite/gcc.dg/float-range-5.c	(revision 0)
@@ -0,0 +1,35 @@
+/* PR 23572 : warnings for out of range floating-point constants 
+   Test that they are NOT pedantic warnings.  */
+/* { dg-compile } */
+/* { dg-options "-pedantic-errors -std=c99" } */
+#include <math.h>
+
+void overflow(void)
+{
+  float f1 = 3.5E+38f;  /* { dg-warning "warning: floating constant exceeds range" } */
+  float f2 = -3.5E+38f; /* { dg-warning "warning: floating constant exceeds range" } */
+  float f3 = FP_INFINITE;
+  float f4 = -FP_INFINITE;
+
+  double d1 = 1.9E+308;  /* { dg-warning "warning: floating constant exceeds range" } */
+  double d2 = -1.9E+308; /* { dg-warning "warning: floating constant exceeds range" } */
+  double d3 = FP_INFINITE;
+  double d4 = -FP_INFINITE;
+}
+
+void underflow(void)
+{
+  float f1 = 3.3E-46f;  /* { dg-warning "warning: floating constant exceeds range" } */
+  float f2 = -3.3E-46f; /* { dg-warning "warning: floating constant exceeds range" } */
+  float f3 = 0;
+  float f4 = -0;
+  float f5 = 0.0;
+  float f6 = -0.0;
+
+  double d1 = 1.4E-325;  /* { dg-warning "warning: floating constant exceeds range" } */
+  double d2 = -1.4E-325; /* { dg-warning "warning: floating constant exceeds range" } */
+  double d3 = 0;
+  double d4 = -0;
+  double d5 = 0.0;
+  double d6 = -0.0;
+}


More information about the Gcc-patches mailing list