🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gdb.bug
Article #8887

GDB 4.6 shouldn't ignore numeric suffixes

#8887
From: Paul Eggert
Date: Wed, 15 Jul 1992 23:28
547 lines
15255 bytes
GDB 4.6 discards numeric suffixes in numbers like 0L and 1.3f.  This can cause
subtle errors when cutting and pasting from source code to GDB.  For example,
on a sparc, ``print 1.1 == 1.1f'' prints 1, where it should print 0.  Here is
a patch that causes GDB to parse such suffixes.  This patch shortens the code
somewhat.  It also fixes another bug: some overflows aren't caught when
parsing large integer constants.

===================================================================
RCS file: defs.h,v
retrieving revision 4.6
diff -c -r4.6 defs.h
*** defs.h	1992/07/14 07:34:21	4.6
--- defs.h	1992/07/15 22:56:11
***************
*** 649,654 ****
--- 649,657 ----
  extern int
  atoi PARAMS ((const char *));				/* 4.10.1.2 */
  
+ extern double
+ strtod PARAMS ((const char *nptr, char **entptr));	/* 4.10.1.4 */
+ 
  #ifndef MALLOC_INCOMPATIBLE
  
  extern PTR
===================================================================
RCS file: c-exp.y,v
retrieving revision 4.6
diff -c -r4.6 c-exp.y
*** c-exp.y	1992/07/14 07:34:19	4.6
--- c-exp.y	1992/07/15 23:01:35
***************
*** 96,104 ****
  
  %union
    {
!     LONGEST lval;
!     unsigned LONGEST ulval;
!     double dval;
      struct symbol *sym;
      struct type *tval;
      struct stoken sval;
--- 96,104 ----
  
  %union
    {
!     LONGEST ival;
!     struct lval { struct type *type; unsigned LONGEST value; } lval;
!     struct dval { struct type *type; double value; } dval;
      struct symbol *sym;
      struct type *tval;
      struct stoken sval;
***************
*** 127,136 ****
  /* Fancy type parsing.  */
  %type <voidval> func_mod direct_abs_decl abs_decl
  %type <tval> ptype
! %type <lval> array_mod
  
! %token <lval> INT CHAR
! %token <ulval> UINT
  %token <dval> FLOAT
  
  /* Both NAME and TYPENAME tokens represent symbols in the input,
--- 127,135 ----
  /* Fancy type parsing.  */
  %type <voidval> func_mod direct_abs_decl abs_decl
  %type <tval> ptype
! %type <ival> array_mod
  
! %token <lval> INT
  %token <dval> FLOAT
  
  /* Both NAME and TYPENAME tokens represent symbols in the input,
***************
*** 151,159 ****
  /* A NAME_OR_INT is a symbol which is not known in the symbol table,
     but which would parse as a valid number in the current input radix.
     E.g. "c" when input_radix==16.  Depending on the parse, it will be
!    turned into a name or into a number.  NAME_OR_UINT ditto.  */
  
! %token <ssym> NAME_OR_INT NAME_OR_UINT
  
  %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
  %token TEMPLATE
--- 150,158 ----
  /* A NAME_OR_INT is a symbol which is not known in the symbol table,
     but which would parse as a valid number in the current input radix.
     E.g. "c" when input_radix==16.  Depending on the parse, it will be
!    turned into a name or into a number.  */
  
! %token <ssym> NAME_OR_INT
  
  %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
  %token TEMPLATE
***************
*** 163,169 ****
     legal basetypes.  */
  %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD
  
! %token <lval> LAST REGNAME
  
  %token <ivar> VARIABLE
  
--- 162,168 ----
     legal basetypes.  */
  %token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD
  
! %token <ival> LAST REGNAME
  
  %token <ivar> VARIABLE
  
***************
*** 433,443 ****
  
  exp	:	INT
  			{ write_exp_elt_opcode (OP_LONG);
! 			  if ($1 == (int) $1 || $1 == (unsigned int) $1)
! 			    write_exp_elt_type (builtin_type_int);
! 			  else
! 			    write_exp_elt_type (BUILTIN_TYPE_LONGEST);
! 			  write_exp_elt_longcst ((LONGEST) $1);
  			  write_exp_elt_opcode (OP_LONG); }
  	;
  
--- 432,439 ----
  
  exp	:	INT
  			{ write_exp_elt_opcode (OP_LONG);
! 			  write_exp_elt_type ($1.type);
! 			  write_exp_elt_longcst ((LONGEST) $1.value);
  			  write_exp_elt_opcode (OP_LONG); }
  	;
  
***************
*** 445,495 ****
  			{ YYSTYPE val;
  			  parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
  			  write_exp_elt_opcode (OP_LONG);
! 			  if (val.lval == (int) val.lval ||
! 			      val.lval == (unsigned int) val.lval)
! 			    write_exp_elt_type (builtin_type_int);
! 			  else
! 			    write_exp_elt_type (BUILTIN_TYPE_LONGEST);
! 			  write_exp_elt_longcst (val.lval);
! 			  write_exp_elt_opcode (OP_LONG); }
! 	;
! 
! exp	:	UINT
! 			{
! 			  write_exp_elt_opcode (OP_LONG);
! 			  if ($1 == (unsigned int) $1)
! 			    write_exp_elt_type (builtin_type_unsigned_int);
! 			  else
! 			    write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
! 			  write_exp_elt_longcst ((LONGEST) $1);
! 			  write_exp_elt_opcode (OP_LONG);
! 			}
! 	;
! 
! exp	:	NAME_OR_UINT
! 			{ YYSTYPE val;
! 			  parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
! 			  write_exp_elt_opcode (OP_LONG);
! 			  if (val.ulval == (unsigned int) val.ulval)
! 			    write_exp_elt_type (builtin_type_unsigned_int);
! 			  else
! 			    write_exp_elt_type (BUILTIN_TYPE_UNSIGNED_LONGEST);
! 			  write_exp_elt_longcst ((LONGEST)val.ulval);
! 			  write_exp_elt_opcode (OP_LONG);
! 			}
! 	;
! 
! exp	:	CHAR
! 			{ write_exp_elt_opcode (OP_LONG);
! 			  write_exp_elt_type (builtin_type_char);
! 			  write_exp_elt_longcst ((LONGEST) $1);
  			  write_exp_elt_opcode (OP_LONG); }
  	;
  
  exp	:	FLOAT
  			{ write_exp_elt_opcode (OP_DOUBLE);
! 			  write_exp_elt_type (builtin_type_double);
! 			  write_exp_elt_dblcst ($1);
  			  write_exp_elt_opcode (OP_DOUBLE); }
  	;
  
--- 441,455 ----
  			{ YYSTYPE val;
  			  parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
  			  write_exp_elt_opcode (OP_LONG);
! 			  write_exp_elt_type (val.lval.type);
! 			  write_exp_elt_longcst ((LONGEST) val.lval.value);
  			  write_exp_elt_opcode (OP_LONG); }
  	;
  
  exp	:	FLOAT
  			{ write_exp_elt_opcode (OP_DOUBLE);
! 			  write_exp_elt_type ($1.type);
! 			  write_exp_elt_dblcst ($1.value);
  			  write_exp_elt_opcode (OP_DOUBLE); }
  	;
  
***************
*** 813,819 ****
  array_mod:	'[' ']'
  			{ $$ = -1; }
  	|	'[' INT ']'
! 			{ $$ = $2; }
  	;
  
  func_mod:	'(' ')'
--- 773,779 ----
  array_mod:	'[' ']'
  			{ $$ = -1; }
  	|	'[' INT ']'
! 			{ $$ = $2.value; }
  	;
  
  func_mod:	'(' ')'
***************
*** 928,934 ****
  	|	BLOCKNAME { $$ = $1.stoken; }
  	|	TYPENAME { $$ = $1.stoken; }
  	|	NAME_OR_INT  { $$ = $1.stoken; }
- 	|	NAME_OR_UINT  { $$ = $1.stoken; }
  	;
  
  name_not_typename :	NAME
--- 888,893 ----
***************
*** 939,945 ****
     =exp) or just an exp.  If name_not_typename was ever used in an lvalue
     context where only a name could occur, this might be useful.
    	|	NAME_OR_INT
-   	|	NAME_OR_UINT
   */
  	;
  
--- 898,903 ----
***************
*** 946,952 ****
  %%
  
  /* Take care of parsing a number (anything that starts with a digit).
!    Set yylval and return the token type; update lexptr.
     LEN is the number of characters in it.  */
  
  /*** Needs some error checking for the float case ***/
--- 904,910 ----
  %%
  
  /* Take care of parsing a number (anything that starts with a digit).
!    Set *PUTITHERE and return the token type.
     LEN is the number of characters in it.  */
  
  /*** Needs some error checking for the float case ***/
***************
*** 958,974 ****
       int parsed_float;
       YYSTYPE *putithere;
  {
!   register LONGEST n = 0;
!   register LONGEST prevn = 0;
    register int i;
    register int c;
    register int base = input_radix;
!   int unsigned_p = 0;
  
    if (parsed_float)
      {
        /* It's a float since it contains a point or an exponent.  */
!       putithere->dval = atof (p);
        return FLOAT;
      }
  
--- 916,954 ----
       int parsed_float;
       YYSTYPE *putithere;
  {
!   register unsigned LONGEST n = 0;
!   register unsigned LONGEST prevn = 0;
    register int i;
    register int c;
    register int base = input_radix;
!   int unsigned_p = 0, long_p = 0;
  
    if (parsed_float)
      {
        /* It's a float since it contains a point or an exponent.  */
!       char *pend;
!       errno = 0;
!       putithere->dval.value = strtod (p, &pend);
!       if (putithere->dval.value != 0 && RANGE_CHECK && errno == ERANGE)
! 	range_error("Overflow on floating point constant.");
!       switch (*pend)
! 	{
! 	  case 'f': case 'F':
! 	    ++pend;
! 	    putithere->dval.type = builtin_type_float;
! 	    break;
! 
! 	  case 'l': case 'L':
! 	    ++pend;
! 	    putithere->dval.type = builtin_type_long_double;
! 	    break;
! 
! 	  default:
! 	    putithere->dval.type = builtin_type_double;
! 	    break;
! 	}
!       if (pend != p + len)
! 	return ERROR;
        return FLOAT;
      }
  
***************
*** 1009,1015 ****
        if (c >= 'A' && c <= 'Z')
  	c += 'a' - 'A';
        if (c != 'l' && c != 'u')
! 	n *= base;
        if (c >= '0' && c <= '9')
  	n += i = c - '0';
        else
--- 989,999 ----
        if (c >= 'A' && c <= 'Z')
  	c += 'a' - 'A';
        if (c != 'l' && c != 'u')
! 	{
! 	  n *= base;
! 	  if (RANGE_CHECK && n / base != prevn)
! 	    range_error("Overflow on numeric constant.");	 
! 	}
        if (c >= '0' && c <= '9')
  	n += i = c - '0';
        else
***************
*** 1016,1053 ****
  	{
  	  if (base > 10 && c >= 'a' && c <= 'f')
  	    n += i = c - 'a' + 10;
- 	  else if (len == 0 && c == 'l')
- 	    ;
- 	  else if (len == 0 && c == 'u')
- 	    unsigned_p = 1;
  	  else
! 	    return ERROR;	/* Char not a digit */
  	}
        if (i >= base)
  	return ERROR;		/* Invalid digit in this base */
-       /* Portably test for overflow (only works for nonzero values, so make
- 	 a second check for zero).  */
-       if((prevn >= n) && n != 0)
- 	 unsigned_p=1;		/* Try something unsigned */
        /* If range checking enabled, portably test for unsigned overflow.  */
!       if(RANGE_CHECK && n!=0)
!       {	
! 	 if((unsigned_p && (unsigned)prevn >= (unsigned)n))
! 	    range_error("Overflow on numeric constant.");	 
!       }
        prevn=n;
      }
  
!   if (unsigned_p)
!     {
!       putithere->ulval = n;
!       return UINT;
!     }
!   else
!     {
!       putithere->lval = n;
!       return INT;
!     }
  }
  
  struct token
--- 1000,1046 ----
  	{
  	  if (base > 10 && c >= 'a' && c <= 'f')
  	    n += i = c - 'a' + 10;
  	  else
! 	    {
! 	      for (;;) {
! 		switch (c)
! 		  {
! 		    case 'l': long_p++; break;
! 		    case 'u': unsigned_p++; break;
! 		    default: return ERROR;
! 		  }
! 		if (len-- == 0)
! 		  break;
! 		c = *p++;
! 	      }
! 	      if (1 < unsigned_p || 2 < long_p)
! 		return ERROR;
! 	      i = 0;
! 	    }
  	}
        if (i >= base)
  	return ERROR;		/* Invalid digit in this base */
        /* If range checking enabled, portably test for unsigned overflow.  */
!       if (RANGE_CHECK && n < prevn)
! 	range_error("Overflow on numeric constant.");	 
        prevn=n;
      }
  
!   putithere->lval.value = n;
!   putithere->lval.type =
!       !(long_p | unsigned_p) && 0 <= (int)n && n == (int) n
!       ? builtin_type_int
!     : !long_p && (base != 10 || unsigned_p) && n == (unsigned) n
!       ? builtin_type_unsigned_int
!     : !unsigned_p && long_p <= 1 && 0 <= (long) n && n == (long) n
!       ? builtin_type_long
!     : long_p <= 1 && n == (unsigned long) n
!       ? builtin_type_unsigned_long
!     : !unsigned_p && 0 <= (LONGEST) n
!       ? builtin_type_long_long
!     : builtin_type_unsigned_long_long;
! 
!   return INT;
  }
  
  struct token
***************
*** 1137,1143 ****
        c = *lexptr++;
        if (c == '\\')
  	c = parse_escape (&lexptr);
!       yylval.lval = c;
        c = *lexptr++;
        if (c != '\'')
  	{
--- 1130,1137 ----
        c = *lexptr++;
        if (c == '\\')
  	c = parse_escape (&lexptr);
!       yylval.lval.type = builtin_type_char;
!       yylval.lval.value = c;
        c = *lexptr++;
        if (c != '\'')
  	{
***************
*** 1151,1157 ****
  	    }
  	  error ("Invalid character constant.");
  	}
!       return CHAR;
  
      case '(':
        paren_depth++;
--- 1145,1151 ----
  	    }
  	  error ("Invalid character constant.");
  	}
!       return INT;
  
      case '(':
        paren_depth++;
***************
*** 1318,1324 ****
        if (c == namelen)
  	{
  	  /* Just dollars (one or two) */
! 	  yylval.lval = - negate;
  	  return LAST;
  	}
        /* Is the rest of the token digits?  */
--- 1312,1318 ----
        if (c == namelen)
  	{
  	  /* Just dollars (one or two) */
! 	  yylval.ival = - negate;
  	  return LAST;
  	}
        /* Is the rest of the token digits?  */
***************
*** 1327,1335 ****
  	  break;
        if (c == namelen)
  	{
! 	  yylval.lval = atoi (tokstart + 1 + negate);
  	  if (negate)
! 	    yylval.lval = - yylval.lval;
  	  return LAST;
  	}
      }
--- 1321,1329 ----
  	  break;
        if (c == namelen)
  	{
! 	  yylval.ival = atoi (tokstart + 1 + negate);
  	  if (negate)
! 	    yylval.ival = - yylval.ival;
  	  return LAST;
  	}
      }
***************
*** 1342,1348 ****
        if (namelen - 1 == strlen (reg_names[c])
  	  && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
  	{
! 	  yylval.lval = c;
  	  return REGNAME;
  	}
      for (c = 0; c < num_std_regs; c++)
--- 1336,1342 ----
        if (namelen - 1 == strlen (reg_names[c])
  	  && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
  	{
! 	  yylval.ival = c;
  	  return REGNAME;
  	}
      for (c = 0; c < num_std_regs; c++)
***************
*** 1349,1355 ****
       if (namelen - 1 == strlen (std_regs[c].name)
  	 && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
         {
! 	 yylval.lval = std_regs[c].regnum;
  	 return REGNAME;
         }
    }
--- 1343,1349 ----
       if (namelen - 1 == strlen (std_regs[c].name)
  	 && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
         {
! 	 yylval.ival = std_regs[c].regnum;
  	 return REGNAME;
         }
    }
***************
*** 1464,1475 ****
  	    yylval.ssym.sym = sym;
  	    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
  	    return NAME_OR_INT;
- 	  }
- 	if (hextype == UINT)
- 	  {
- 	    yylval.ssym.sym = sym;
- 	    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
- 	    return NAME_OR_UINT;
  	  }
        }
  
--- 1458,1463 ----
Technical Details
Message-ID: <9207152328.AA21044@farside.twinsun.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggert

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f5053,23864689a32aae65,start
X-Google-Attributes: gidf5053,public
X-Google-ArrivalTime: 1992-07-15 17:04:02 PST
Newsgroups: gnu.gdb.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!twinsun.COM!eggert
From: eggert@twinsun.COM (Paul Eggert)
Subject: GDB 4.6 shouldn't ignore numeric suffixes
Message-ID: <9207152328.AA21044@farside.twinsun.com>
Sender: gnulists@ai.mit.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 15 Jul 1992 23:28:39 GMT
Approved: bug-gdb@prep.ai.mit.edu
Lines: 548