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>
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
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. */
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. */
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
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)
{
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 (!cmp_significand_0 (r))
goto underflow;
goto is_a_zero;
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 (r->cl == rvc_zero)
goto underflow;
goto is_a_zero;
if (*str == 'e' || *str == 'E')
{
@ -1981,15 +1982,19 @@ real_from_string (REAL_VALUE_TYPE *r, const char *str)
}
r->sign = sign;
return;
return 0;
is_a_zero:
get_zero (r, sign);
return 0;
underflow:
get_zero (r, sign);
return;
return -1;
overflow:
get_inf (r, sign);
return;
return 1;
}
/* 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 *,
const REAL_VALUE_TYPE *);
/* Initialize R from a decimal or hexadecimal string. */
extern void real_from_string (REAL_VALUE_TYPE *, const char *);
/* Initialize R from a decimal or hexadecimal string. Return -1 if
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. */
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>
PR fortran/31262

View File

@ -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'" } */
}

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;
}