This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] A patch for parse_number (c-exp.y) to recognize 1.25f


> To fix this kind of false-negative and not to introduce false-positive, I 
> am thinking of changing the second format in sscanf to "%s" (string).  
> Thus the parser could get the trailing characters following the float. 
> Then we can add some code to parse them to eliminate false-positive.  Any 
> points on this idea?  Is it worthwhile to do this?  Please comment.  TIA.

Following the above point, I coded another patch.  It can fix the problem 
and don't introduce any false-positive mentioned above.  I had also coded 
a testcase for that.  Had tested on i386.  With the patched GDB, it 
reported 18 PASS; with the original GDB, it report 9 PASS and 9 FAIL (all 
of these failure is due to the fact that GDB can't handle the suffix 
following the float constants.)

IMHO, there are yet another advantage for this patch: it is easy to be
extended to handle other suffixes, such "df" for _Decimal32, "dd" for 
_Decimal64 and "dl" for _Decimal128, all of which are described in IEEE 
754R for decimal floating point.

Here goes the patch and the testcase.

2005-09-15  Wu Zhou  <woodzltc@cn.ibm.com>

	* c-exp.y (parse-number): Modify the float parsing logic to let it 
	recognize the suffix.

Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.29
diff -c -3 -p -r1.29 c-exp.y
*** c-exp.y	8 Mar 2005 14:35:17 -0000	1.29
--- c-exp.y	15 Sep 2005 08:26:36 -0000
*************** parse_number (p, len, parsed_float, puti
*** 1074,1116 ****
    if (parsed_float)
      {
        /* It's a float since it contains a point or an exponent.  */
!       char c;
        int num = 0;	/* number of tokens scanned by scanf */
        char saved_char = p[len];
  
        p[len] = 0;	/* null-terminate the token */
        if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
! 	num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
        else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
! 	num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
        else
  	{
  #ifdef SCANF_HAS_LONG_DOUBLE
! 	  num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
  #else
  	  /* Scan it into a double, then assign it to the long double.
  	     This at least wins with values representable in the range
  	     of doubles. */
  	  double temp;
! 	  num = sscanf (p, "%lg%c", &temp,&c);
  	  putithere->typed_val_float.dval = temp;
  #endif
  	}
        p[len] = saved_char;	/* restore the input stream */
!       if (num != 1) 		/* check scanf found ONLY a float ... */
! 	return ERROR;
!       /* See if it has `f' or `l' suffix (float or long double).  */
! 
!       c = tolower (p[len - 1]);
! 
!       if (c == 'f')
! 	putithere->typed_val_float.type = builtin_type (current_gdbarch)->builtin_float;
!       else if (c == 'l')
! 	putithere->typed_val_float.type = builtin_type (current_gdbarch)->builtin_long_double;
!       else if (isdigit (c) || c == '.')
! 	putithere->typed_val_float.type = builtin_type (current_gdbarch)->builtin_double;
!       else
! 	return ERROR;
  
        return FLOAT;
      }
--- 1074,1121 ----
    if (parsed_float)
      {
        /* It's a float since it contains a point or an exponent.  */
!       char *s = malloc (len);
        int num = 0;	/* number of tokens scanned by scanf */
        char saved_char = p[len];
  
        p[len] = 0;	/* null-terminate the token */
+ 
        if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
! 	num = sscanf (p, "%g%s", (float *) &putithere->typed_val_float.dval,s);
        else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
! 	num = sscanf (p, "%lg%s", (double *) &putithere->typed_val_float.dval,s);
        else
  	{
  #ifdef SCANF_HAS_LONG_DOUBLE
! 	  num = sscanf (p, "%Lg%s", &putithere->typed_val_float.dval,s);
  #else
  	  /* Scan it into a double, then assign it to the long double.
  	     This at least wins with values representable in the range
  	     of doubles. */
  	  double temp;
! 	  num = sscanf (p, "%lg%s", &temp,s);
  	  putithere->typed_val_float.dval = temp;
  #endif
  	}
        p[len] = saved_char;	/* restore the input stream */
! 
!       if (num == 1)
! 	putithere->typed_val_float.type = builtin_type (current_gdbarch)
! 					    ->builtin_double;
! 
!       if (num == 2 )
! 	{
! 	  /* See if it has any float suffix: 'f' for float, 'l' for long 
! 	     double.  */
! 	  if (!strcasecmp (s, "f"))
! 	    putithere->typed_val_float.type = builtin_type (current_gdbarch)
! 						->builtin_float;
! 	  else if (!strcasecmp (s, "l"))
! 	    putithere->typed_val_float.type = builtin_type (current_gdbarch)
! 						->builtin_long_double;
! 	  else
! 	    return ERROR;
! 	}
  
        return FLOAT;
      }

2005-09-15  Wu Zhou  <woodzltc@cn.ibm.com>

	* bfp-test.c: New file.
	* bfp-test.exp: New testcase.

Index: gdb.base/bfp-test.c
===================================================================
RCS file: gdb.base/bfp-test.c
diff -N gdb.base/bfp-test.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gdb.base/bfp-test.c	15 Sep 2005 06:49:51 -0000
***************
*** 0 ****
--- 1,15 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+ float b32;
+ double b64;
+ long double b128;
+ 
+ int main()
+ {
+   b32 = 1.5f;
+   b64 = 2.25;
+   b128 = 3.375l;
+  
+   return 0;
+ }
Index: gdb.base/bfp-test.exp
===================================================================
RCS file: gdb.base/bfp-test.exp
diff -N gdb.base/bfp-test.exp
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gdb.base/bfp-test.exp	15 Sep 2005 06:49:51 -0000
***************
*** 0 ****
--- 1,109 ----
+ # Copyright 2005 Free Software Foundation, Inc.
+ 
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ 
+ # This file is part of the gdb testsuite.  It is intended to test that
+ # gdb could correctly handle floating point constant with a suffix.
+ 
+ if $tracelevel {
+     strace $tracelevel
+ }
+ 
+ set testfile "bfp-test"
+ set srcfile ${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested "Couldn't compile ${srcfile}"
+     return -1
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ 
+ if ![runto_main] then {
+     perror "couldn't run to breakpoint"
+     continue
+ }
+ 
+ # Run to the breakpoint at return.
+ set bp_location [gdb_get_line_number "return"]
+ gdb_test "break $bp_location" \
+     "Breakpoint.*at.* file .*$srcfile, line $bp_location\\." \
+     "breakpoint at return"
+ gdb_test "continue" \
+     "Continuing\\..*Breakpoint.*" \
+     "continue to breakpoint"
+ 
+ # Print the original value of b32, b64 and b128.
+ gdb_test "print b32" ".*1 = 1\.5.*" "The original value of b32 is 1.5"
+ gdb_test "print b64" ".*2 = 2\.25.*" "The original value of b64 is 2.25"
+ gdb_test "print b128" ".*3 = 3\.375.*" "The original value of b128 is 3.375"
+ 
+ # Test that gdb could correctly recognize float constant expression with a suffix. 
+ gdb_test "print b32=-1.5f" ".*4 = -1\.5.*" "Try to change b32 to -1.5 with 'print b32=-1.5f'"
+ gdb_test "print b64=-2.25f" ".*5 = -2\.25.*" "Try to change b64 to -2.25 with 'print b64=-2.25f'"
+ gdb_test "print b128=-3.375l" ".*6 = -3\.375.*" "Try to change b128 to -3.375 with 'print b128=-3.375l'"
+ 
+ # Test that gdb could handle the above correctly with "set var" command.
+ send_gdb "set var b32=10.5f\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { pass "set var b32=10.5f" }
+     -re "Invalid number" { fail "do not recognize 10.5f" }
+     timeout     {fail "set var b32=10.5f" }
+   }
+ send_gdb "set var b64=20.25f\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { pass "set var b64=20.25f" }
+     -re "Invalid number" { fail "do not recognize 20.25f" }
+     timeout     {fail "set var b64=20.25f" }
+   }
+ send_gdb "set var b128=30.375f\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { pass "set var b128=30.375f" }
+     -re "Invalid number" { fail "do not recognize 30.375f" }
+     timeout     {fail "set var b128=30.375f" }
+   }
+ gdb_test "print b32" ".*7 = 10\.5.*" "The value of b32 is changed to 10.5"
+ gdb_test "print b64" ".*8 = 20\.25.*" "The value of b64 is changed to 20.25"
+ gdb_test "print b128" ".*9 = 30\.375.*" "The value of b128 is changed to 30.375"
+ 
+ # Test that gdb could handle invalid suffix correctly.
+ send_gdb "set var b32=100.5a\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { fail "don't report error on 100.5a" }
+     -re "Invalid number" { pass "100.5a is invalid number" }
+     timeout     {fail "set var b32=100.5a" }
+   }
+ send_gdb "set var b64=200.25x\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { fail "don't report error on 200.25x" }
+     -re "Invalid number" { pass "200.25x is invalid number" }
+     timeout     {fail "set var b64=200.25x" }
+   }
+ send_gdb "set var b128=300.375fl\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { fail "don't report error on 300.375fl" }
+     -re "Invalid number" { pass "300.375fl is invalid number" }
+     timeout     {fail "set var b128=300.375fl" }
+   }
+ send_gdb "set var b32=300.375fff\n"
+ gdb_expect {
+     -re "$gdb_prompt $" { fail "don't report error on 300.375fff" }
+     -re "Invalid number" { pass "300.375fff is invalid number" }
+     timeout     {fail "set var b128=300.375fff" }
+   }
+  

Regards
- Wu Zhou


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]