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