Article View: gnu.gcc.bug
Article #194bugs in GCC 2.2.2 floating point range and suffix checks
From: Paul Eggert
Date: Fri, 24 Jul 1992 19:21
Date: Fri, 24 Jul 1992 19:21
266 lines
8139 bytes
8139 bytes
1. GCC 2.2.2 (sparc, SunOS 4.1.2) does not issue a diagnostic for the program:
double d = 1.0fl;
even though the conflicting suffixes `f' and `l' violate C syntax.
2. For the program
float f = 1e400f;
`gcc -pedantic' issues the following redundant diagnostics.
t.c:1: warning: floating point number exceeds range of `double'
t.c:1: warning: floating point number exceeds range of `float'
Here is a patch. This patch affects both the C and the C++ lexers, and
assumes that you've already applied the patch ``gcc 2.2.2 fp constant overflow
check should use REAL_VALUES_LESS'' that I reported on June 15. The code in
the two 2.2.2 lexers had diverged slightly, because some changes were applied
to the C lexer but not the C++ lexer. The patch below updates the C++ lexer
to match the C lexer.
Fri Jul 24 19:09:02 1992 Paul Eggert (eggert@twinsun.com)
* c-lex.c, cp-lex.c (yylex): Diagnose `1.0fl'. Issue just one
diagnostic for `1e1000000f'.
===================================================================
RCS file: c-lex.c,v
retrieving revision 2.2.2.1
diff -c -r2.2.2.1 c-lex.c
*** c-lex.c 1992/06/15 20:45:16 2.2.2.1
--- c-lex.c 1992/07/24 18:54:59
***************
*** 1245,1252 ****
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
! char f_seen = 0;
! char l_seen = 0;
REAL_VALUE_TYPE value;
jmp_buf handler;
--- 1245,1251 ----
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
! int garbage_chars = 0, exceeds_double = 0;
REAL_VALUE_TYPE value;
jmp_buf handler;
***************
*** 1297,1348 ****
if (REAL_VALUES_LESS (dconst1, value)
|| REAL_VALUES_LESS (value, dconstm1))
pedwarn ("floating point number exceeds range of `double'");
}
#endif
/* Read the suffixes to choose a data type. */
! while (1)
{
! if (c == 'f' || c == 'F')
! {
! if (f_seen)
! error ("two `f's in floating constant");
! else
! {
! f_seen = 1;
! type = float_type_node;
! value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
! if (REAL_VALUE_ISINF (value) && pedantic)
! pedwarn ("floating point number exceeds range of `float'");
! }
! }
! else if (c == 'l' || c == 'L')
! {
! if (l_seen)
! error ("two `l's in floating constant");
! l_seen = 1;
! type = long_double_type_node;
! }
! else
! {
! if (isalnum (c))
! {
! error ("garbage at end of number");
! while (isalnum (c))
! {
! if (p >= token_buffer + maxtoken - 3)
! p = extend_token_buffer (p);
! *p++ = c;
! c = getc (finput);
! }
! }
! break;
! }
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getc (finput);
}
/* Create a node with determined type and value. */
yylval.ttype = build_real (type, value);
--- 1296,1331 ----
if (REAL_VALUES_LESS (dconst1, value)
|| REAL_VALUES_LESS (value, dconstm1))
pedwarn ("floating point number exceeds range of `double'");
+ exceeds_double = 1;
}
#endif
/* Read the suffixes to choose a data type. */
! switch (c)
{
! case 'f': case 'F':
! type = float_type_node;
! value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
! if (REAL_VALUE_ISINF (value) && ! exceeds_double && pedantic)
! pedwarn ("floating point number exceeds range of `float'");
! garbage_chars = -1;
! break;
!
! case 'l': case 'L':
! type = long_double_type_node;
! garbage_chars = -1;
! break;
! }
! while (isalnum (c))
! {
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getc (finput);
+ garbage_chars++;
}
+ if (garbage_chars > 0)
+ error ("garbage at end of number");
/* Create a node with determined type and value. */
yylval.ttype = build_real (type, value);
===================================================================
RCS file: cp-lex.c,v
retrieving revision 2.2.2.1
diff -c -r2.2.2.1 cp-lex.c
*** cp-lex.c 1992/06/15 20:45:16 2.2.2.1
--- cp-lex.c 1992/07/24 18:55:24
***************
*** 2887,2894 ****
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
! char f_seen = 0;
! char l_seen = 0;
REAL_VALUE_TYPE value;
jmp_buf handler;
--- 2887,2893 ----
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
! int garbage_chars = 0, exceeds_double = 0;
REAL_VALUE_TYPE value;
jmp_buf handler;
***************
*** 2932,2985 ****
set_float_handler (0);
}
#ifdef ERANGE
! if (errno == ERANGE && !flag_traditional)
{
/* ERANGE is also reported for underflow,
so test the value to distinguish overflow from that. */
! if (REAL_VALUES_LESS (dconst1, value)
! || REAL_VALUES_LESS (value, dconstm1))
! warning ("floating point number exceeds range of `double'");
}
#endif
/* Read the suffixes to choose a data type. */
! while (1)
{
! if (c == 'f' || c == 'F')
! {
! if (f_seen)
! error ("two `f's in floating constant");
! f_seen = 1;
! type = float_type_node;
! value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
! }
! else if (c == 'l' || c == 'L')
! {
! if (l_seen)
! error ("two `l's in floating constant");
! l_seen = 1;
! type = long_double_type_node;
! }
! else
! {
! if (isalnum (c))
! {
! error ("garbage at end of number");
! while (isalnum (c))
! {
! if (p >= token_buffer + maxtoken - 3)
! p = extend_token_buffer (p);
! *p++ = c;
! c = getch ();
! }
! }
! break;
! }
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
}
/* Create a node with determined type and value. */
yylval.ttype = build_real (type, value);
--- 2931,2973 ----
set_float_handler (0);
}
#ifdef ERANGE
! if (errno == ERANGE && !flag_traditional && pedantic)
{
/* ERANGE is also reported for underflow,
so test the value to distinguish overflow from that. */
! if (REAL_VALUES_LESS (dconst1, value)
! || REAL_VALUES_LESS (value, dconstm1))
! pedwarn ("floating point number exceeds range of `double'");
! exceeds_double = 1;
}
#endif
/* Read the suffixes to choose a data type. */
! switch (c)
{
! case 'f': case 'F':
! type = float_type_node;
! value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
! if (REAL_VALUE_ISINF (value) && ! exceeds_double && pedantic)
! pedwarn ("floating point number exceeds range of `float'");
! garbage_chars = -1;
! break;
!
! case 'l': case 'L':
! type = long_double_type_node;
! garbage_chars = -1;
! break;
! }
! while (isalnum (c))
! {
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
+ garbage_chars++;
}
+ if (garbage_chars > 0)
+ error ("garbage at end of number");
/* Create a node with determined type and value. */
yylval.ttype = build_real (type, value);
Technical Details
Message-ID:
<9207241921.AA22356@farside.twinsun.com>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggertShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggert From: eggert@twinsun.COM (Paul Eggert) Subject: bugs in GCC 2.2.2 floating point range and suffix checks Message-ID: <9207241921.AA22356@farside.twinsun.com> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Fri, 24 Jul 1992 19:21:07 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 267