🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Paul Eggert Fri, 24 Jul 1992 19:21
bugs in GCC 2.2.2 floating point range and suffix checks
#194
Author: Paul Eggert
Date: Fri, 24 Jul 1992 19:21
266 lines
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);
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads