re PR other/23572 (No warning for assigning a value to a 'float' variable that overflows with option -Wextra)

2007-03-22  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.
	* real.c (real_from_string): Return -1 if underflow, +1 if overflow
	and 0 otherwise.
	* real.h (real_from_string): Update declaration
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.

From-SVN: r123137
This commit is contained in:
Manuel López-Ibáñez 2007-03-22 23:04:24 +00:00
parent efa591c57e
commit 92ef5cf999
9 changed files with 171 additions and 19 deletions

View File

@ -1,3 +1,13 @@
2007-03-22 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.
* real.c (real_from_string): Return -1 if underflow, +1 if overflow
and 0 otherwise.
* real.h (real_from_string): Update declaration
2007-03-22 Kai Tietz <kai.tietz@onevision.com> 2007-03-22 Kai Tietz <kai.tietz@onevision.com>
Richard Henderson <rth@redhat.com> Richard Henderson <rth@redhat.com>

View File

@ -681,11 +681,23 @@ interpret_float (const cpp_token *token, unsigned int flags)
/* Both C and C++ require a diagnostic for a floating constant /* Both C and C++ require a diagnostic for a floating constant
outside the range of representable values of its type. Since we outside the range of representable values of its type. Since we
have __builtin_inf* to produce an infinity, it might now be have __builtin_inf* to produce an infinity, this is now a
appropriate for this to be a mandatory pedwarn rather than mandatory pedwarn if the target does not support infinities. */
conditioned on -pedantic. */ if (REAL_VALUE_ISINF (real))
if (REAL_VALUE_ISINF (real) && pedantic) {
if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
pedwarn ("floating constant exceeds range of %qT", 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. */
else if (REAL_VALUES_EQUAL (real, dconst0))
{
REAL_VALUE_TYPE realvoidmode;
int overflow = real_from_string (&realvoidmode, copy);
if (overflow < 0 || !REAL_VALUES_EQUAL (realvoidmode, dconst0))
warning (OPT_Woverflow, "floating constant truncated to zero");
}
/* Create a node with determined type and value. */ /* Create a node with determined type and value. */
value = build_real (type, real); value = build_real (type, real);

View File

@ -1791,9 +1791,10 @@ real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size,
} }
/* Initialize R from a decimal or hexadecimal string. The string is /* Initialize R from a decimal or hexadecimal string. The string is
assumed to have been syntax checked already. */ assumed to have been syntax checked already. Return -1 if the
value underflows, +1 if overflows, and 0 otherwise. */
void int
real_from_string (REAL_VALUE_TYPE *r, const char *str) real_from_string (REAL_VALUE_TYPE *r, const char *str)
{ {
int exp = 0; int exp = 0;
@ -1865,7 +1866,7 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
/* If the mantissa is zero, ignore the exponent. */ /* If the mantissa is zero, ignore the exponent. */
if (!cmp_significand_0 (r)) if (!cmp_significand_0 (r))
goto underflow; goto is_a_zero;
if (*str == 'p' || *str == 'P') if (*str == 'p' || *str == 'P')
{ {
@ -1941,7 +1942,7 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
/* If the mantissa is zero, ignore the exponent. */ /* If the mantissa is zero, ignore the exponent. */
if (r->cl == rvc_zero) if (r->cl == rvc_zero)
goto underflow; goto is_a_zero;
if (*str == 'e' || *str == 'E') if (*str == 'e' || *str == 'E')
{ {
@ -1981,15 +1982,19 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
} }
r->sign = sign; r->sign = sign;
return; return 0;
is_a_zero:
get_zero (r, sign);
return 0;
underflow: underflow:
get_zero (r, sign); get_zero (r, sign);
return; return -1;
overflow: overflow:
get_inf (r, sign); get_inf (r, sign);
return; return 1;
} }
/* Legacy. Similar, but return the result directly. */ /* Legacy. Similar, but return the result directly. */

View File

@ -224,8 +224,9 @@ extern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *);
extern void real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *, extern void real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *,
const REAL_VALUE_TYPE *); const REAL_VALUE_TYPE *);
/* Initialize R from a decimal or hexadecimal string. */ /* Initialize R from a decimal or hexadecimal string. Return -1 if
extern void real_from_string (REAL_VALUE_TYPE *, const char *); the value underflows, +1 if overflows, and 0 otherwise. */
extern int real_from_string (REAL_VALUE_TYPE *, const char *);
/* Wrapper to allow different internal representation for decimal floats. */ /* Wrapper to allow different internal representation for decimal floats. */
extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, enum machine_mode); extern void real_from_string3 (REAL_VALUE_TYPE *, const char *, enum machine_mode);

View File

@ -1,3 +1,11 @@
2007-03-22 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR other/23572
* 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.
2007-03-22 Francois-Xavier Coudert <coudert@clipper.ens.fr> 2007-03-22 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/31262 PR fortran/31262

View File

@ -1,13 +1,14 @@
/* Floating constants outside the range of their type should receive a /* 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> */ /* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-ansi -pedantic-errors" } */ /* { dg-options "-ansi -pedantic-errors -Woverflow" } */
void void
f (void) f (void)
{ {
float a = 1e+100000000f; /* { dg-error "error: floating constant exceeds range of 'float'" } */ float a = 1e+100000000f; /* { dg-warning "warning: floating constant exceeds range of 'float'" "" } */
double b = 1e+100000000; /* { dg-error "error: floating constant exceeds range of 'double'" } */ double b = 1e+100000000; /* { dg-warning "warning: floating constant exceeds range of 'double'" } */
long double c = 1e+100000000l; /* { dg-error "error: floating constant exceeds range of 'long double'" } */ long double c = 1e+100000000l; /* { dg-warning "warning: floating constant exceeds range of 'long double'" } */
} }

View File

@ -0,0 +1,38 @@
/* 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 f11 = 3.3E-10000000000000000000f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f22 = -3.3E-10000000000000000000f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f1 = 3.3E-46f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f2 = -3.3E-46f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f3 = 0;
float f4 = -0;
float f5 = 0.0;
float f6 = -0.0;
double d11 = 3.3E-10000000000000000000; /* { dg-warning "warning: floating constant truncated to zero" } */
double d22 = -3.3E-10000000000000000000; /* { dg-warning "warning: floating constant truncated to zero" } */
double d1 = 1.4E-325; /* { dg-warning "warning: floating constant truncated to zero" } */
double d2 = -1.4E-325; /* { dg-warning "warning: floating constant truncated to zero" } */
double d3 = 0;
double d4 = -0;
double d5 = 0.0;
double d6 = -0.0;
}

View File

@ -0,0 +1,38 @@
/* 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 f11 = 3.3E-10000000000000000000f;
float f22 = -3.3E-10000000000000000000f;
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 d11 = 3.3E-10000000000000000000;
double d22 = -3.3E-10000000000000000000;
double d1 = 1.4E-325;
double d2 = -1.4E-325;
double d3 = 0;
double d4 = -0;
double d5 = 0.0;
double d6 = -0.0;
}

View File

@ -0,0 +1,39 @@
/* 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 f11 = 3.3E-10000000000000000000f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f22 = -3.3E-10000000000000000000f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f1 = 3.3E-46f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f2 = -3.3E-46f; /* { dg-warning "warning: floating constant truncated to zero" } */
float f3 = 0;
float f4 = -0;
float f5 = 0.0;
float f6 = -0.0;
double d11 = 3.3E-10000000000000000000; /* { dg-warning "warning: floating constant truncated to zero" } */
double d22 = -3.3E-10000000000000000000; /* { dg-warning "warning: floating constant truncated to zero" } */
double d1 = 1.4E-325; /* { dg-warning "warning: floating constant truncated to zero" } */
double d2 = -1.4E-325; /* { dg-warning "warning: floating constant truncated to zero" } */
double d3 = 0;
double d4 = -0;
double d5 = 0.0;
double d6 = -0.0;
}