PR 23572 warnings for out of range floating-point constants

Manuel López-Ibáñez lopezibanez@gmail.com
Sun Jan 21 15:57:00 GMT 2007


:ADDPATCH c/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. It also adds the possibility of enabling the warning not
only with -pedantic but also with -Wconversion (since it fits its
definition).

Bootstrapped and regression tested with --enable-languages=all.

I could only test using i686-pc-linux-gnu. Any suggestions to make the
tests more portable?

OK for mainline?

2007-01-21  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

  PR other/23572
  * c-lex.c (interpret_float): Warn if the constant is too small and
thus it is taken as 0. Warn with -pedantic or -Wconversion.

testsuite/
  * gcc.dg/gcc.dg/pr23572.c: New. Test with -pedantic
  * gcc.dg/gcc.dg/pr23572-2.c: New. Test with -pedantic-errors.
  * gcc.dg/gcc.dg/pr23572-3.c: New. Test with -Wconversion.
-------------- next part --------------
Index: gcc/c-lex.c
===================================================================
--- gcc/c-lex.c	(revision 120783)
+++ 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,22 @@ 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);
+  if (REAL_VALUE_ISINF (real) 
+      || (REAL_VALUES_IDENTICAL (real, dconst0) 
+	  && !REAL_VALUES_IDENTICAL (realvoidmode, dconst0))) 
+    {
+      if (pedantic)
+	pedwarn ("floating constant exceeds range of %qT", type);
+      else if (warn_conversion)
+	warning (OPT_Wconversion, "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/pr23572.c
===================================================================
--- gcc/testsuite/gcc.dg/pr23572.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr23572.c	(revision 0)
@@ -0,0 +1,34 @@
+/* PR 23572 : warnings for out of range floating-point constants.  */
+/* { dg-compile } */
+/* { dg-options "-pedantic -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" } */
+  float d3 = FP_INFINITE;
+  float 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/pr23572-3.c
===================================================================
--- gcc/testsuite/gcc.dg/pr23572-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr23572-3.c	(revision 0)
@@ -0,0 +1,35 @@
+/* PR 23572 : warnings for out of range floating-point constants 
+   Warn also with -Wconversion.  */
+/* { dg-compile } */
+/* { dg-options "-Wconversion -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" } */
+  float d3 = FP_INFINITE;
+  float 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/pr23572-2.c
===================================================================
--- gcc/testsuite/gcc.dg/pr23572-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr23572-2.c	(revision 0)
@@ -0,0 +1,34 @@
+/* PR 23572 : warnings for out of range floating-point constants.  */
+/* { dg-compile } */
+/* { dg-options "-pedantic-errors -std=c99" } */
+#include <math.h>
+
+void overflow(void)
+{
+  float f1 = 3.5E+38f;  /* { dg-error "error: floating constant exceeds range" } */
+  float f2 = -3.5E+38f; /* { dg-error "error: floating constant exceeds range" } */
+  float f3 = FP_INFINITE;
+  float f4 = -FP_INFINITE;
+
+  double d1 = 1.9E+308;  /* { dg-error "error: floating constant exceeds range" } */
+  double d2 = -1.9E+308; /* { dg-error "error: floating constant exceeds range" } */
+  float d3 = FP_INFINITE;
+  float d4 = -FP_INFINITE;
+}
+
+void underflow(void)
+{
+  float f1 = 3.3E-46f;  /* { dg-error "error: floating constant exceeds range" } */
+  float f2 = -3.3E-46f; /* { dg-error "error: floating constant exceeds range" } */
+  float f3 = 0;
+  float f4 = -0;
+  float f5 = 0.0;
+  float f6 = -0.0;
+
+  double d1 = 1.4E-325;  /* { dg-error "error: floating constant exceeds range" } */
+  double d2 = -1.4E-325; /* { dg-error "error: 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