[PATCH] Fix fixed-point regression with recent GCC

Joel Brobecker brobecker@adacore.com
Mon Jan 25 07:52:01 GMT 2021


Hello,

On Fri, Jan 22, 2021 at 01:40:32PM -0700, Tom Tromey wrote:
> A recent version of GCC changed how fixed-point types are described.
> For example, a denominator in one test case now looks like:
> 
>     GNU_denominator      (exprloc)
>      [ 0] implicit_value: 16 byte block: 00 00 b8 9d 0d 69 55 a0 01 00 00 00 00 00 00 00
> 
> ... the difference being that this now uses exprloc and emits a
> DW_OP_implicit_value for the 16-byte block.  (DWARF 5 still uses
> DW_FORM_data16.)
> 
> This change was made here:
> 
>     https://gcc.gnu.org/pipermail/gcc-patches/2020-December/560897.html
> 
> This patch updates gdb to handle this situation.
> 
> Note that, before GCC 11, this test would not give the same answer.
> Earlier versions of GCC fell back to GNAT encodings for this case.
> 
> gdb/ChangeLog
> 2021-01-22  Tom Tromey  <tromey@adacore.com>
> 
> 	* dwarf2/read.c (get_mpz): New function.
> 	(get_dwarf2_rational_constant): Use it.
> 
> gdb/testsuite/ChangeLog
> 2021-01-22  Tom Tromey  <tromey@adacore.com>
> 
> 	* gdb.ada/fixed_points.exp: Add regression test.
> 	* gdb.ada/fixed_points/fixed_points.adb (FP5_Var): New variable.
> 	* gdb.ada/fixed_points/pck.adb (Delta5, FP5_Type): New.

FWIW, I suspect Tom is putting this patch up for review because
it touches areas outside ada-*, but I wanted to mention also that
I reviewed this patch when it was pushed internally at AdaCore,
and it looked good to me.

> ---
>  gdb/ChangeLog                                 |  5 ++
>  gdb/dwarf2/read.c                             | 61 +++++++++++++------
>  gdb/testsuite/ChangeLog                       |  6 ++
>  gdb/testsuite/gdb.ada/fixed_points.exp        |  5 ++
>  .../gdb.ada/fixed_points/fixed_points.adb     |  3 +
>  gdb/testsuite/gdb.ada/fixed_points/pck.ads    |  4 ++
>  6 files changed, 65 insertions(+), 19 deletions(-)
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 309ff8331e7..ae95c650f1e 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -18228,6 +18228,46 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
>    return this_type;
>  }
>  
> +/* Helper for get_dwarf2_rational_constant that computes the value of
> +   a given gmp_mpz given an attribute.  */
> +
> +static void
> +get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
> +{
> +  /* GCC will sometimes emit a 16-byte constant value as a DWARF
> +     location expression that pushes an implicit value.  */
> +  if (attr->form == DW_FORM_exprloc)
> +    {
> +      dwarf_block *blk = attr->as_block ();
> +      if (blk->size > 0 && blk->data[0] == DW_OP_implicit_value)
> +	{
> +	  uint64_t len;
> +	  const gdb_byte *ptr = safe_read_uleb128 (blk->data + 1,
> +						   blk->data + blk->size,
> +						   &len);
> +	  if (ptr - blk->data + len <= blk->size)
> +	    {
> +	      mpz_import (value->val, len,
> +			  bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
> +			  1, 0, 0, ptr);
> +	      return;
> +	    }
> +	}
> +
> +      /* On failure set it to 1.  */
> +      *value = gdb_mpz (1);
> +    }
> +  else if (attr->form_is_block ())
> +    {
> +      dwarf_block *blk = attr->as_block ();
> +      mpz_import (value->val, blk->size,
> +		  bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
> +		  1, 0, 0, blk->data);
> +    }
> +  else
> +    *value = gdb_mpz (attr->constant_value (1));
> +}
> +
>  /* Assuming DIE is a rational DW_TAG_constant, read the DIE's
>     numerator and denominator into NUMERATOR and DENOMINATOR (resp).
>  
> @@ -18254,25 +18294,8 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu,
>    if (num_attr == nullptr || denom_attr == nullptr)
>      return;
>  
> -  if (num_attr->form_is_block ())
> -    {
> -      dwarf_block *blk = num_attr->as_block ();
> -      mpz_import (numerator->val, blk->size,
> -		  bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
> -		  1, 0, 0, blk->data);
> -    }
> -  else
> -    *numerator = gdb_mpz (num_attr->constant_value (1));
> -
> -  if (denom_attr->form_is_block ())
> -    {
> -      dwarf_block *blk = denom_attr->as_block ();
> -      mpz_import (denominator->val, blk->size,
> -		  bfd_big_endian (cu->per_objfile->objfile->obfd) ? 1 : -1,
> -		  1, 0, 0, blk->data);
> -    }
> -  else
> -    *denominator = gdb_mpz (denom_attr->constant_value (1));
> +  get_mpz (cu, numerator, num_attr);
> +  get_mpz (cu, denominator, denom_attr);
>  }
>  
>  /* Same as get_dwarf2_rational_constant, but extracting an unsigned
> diff --git a/gdb/testsuite/gdb.ada/fixed_points.exp b/gdb/testsuite/gdb.ada/fixed_points.exp
> index 0d244534975..ac45ef92ce9 100644
> --- a/gdb/testsuite/gdb.ada/fixed_points.exp
> +++ b/gdb/testsuite/gdb.ada/fixed_points.exp
> @@ -123,5 +123,10 @@ foreach_with_prefix scenario {all minimal} {
>  	gdb_test "print fp4_var * 1" $fp4
>  	gdb_test "print 1 * fp4_var" $fp4
>  	gdb_test "print fp4_var / 1" $fp4
> +
> +	# This only started working in GCC 11.
> +	if {[test_compiler_info {gcc-11-*}]} {
> +	    gdb_test "print fp5_var" " = 3e-19"
> +	}
>      }
>  }
> diff --git a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb
> index cc2c6377761..4298cdf899e 100644
> --- a/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb
> +++ b/gdb/testsuite/gdb.ada/fixed_points/fixed_points.adb
> @@ -55,6 +55,8 @@ procedure Fixed_Points is
>     Overprecise_Object : Overprecise_Fixed_Point :=
>       Overprecise_Fixed_Point'Small;
>  
> +   FP5_Var : FP5_Type := 3 * Delta5;
> +
>  begin
>     Base_Object := 1.0/16.0;   -- Set breakpoint here
>     Subtype_Object := 1.0/16.0;
> @@ -64,4 +66,5 @@ begin
>     Do_Nothing (FP2_Var'Address);
>     Do_Nothing (FP3_Var'Address);
>     Do_Nothing (FP4_Var'Address);
> +   Do_Nothing (FP5_Var'Address);
>  end Fixed_Points;
> diff --git a/gdb/testsuite/gdb.ada/fixed_points/pck.ads b/gdb/testsuite/gdb.ada/fixed_points/pck.ads
> index b5c1bc01c44..3bdf0595076 100644
> --- a/gdb/testsuite/gdb.ada/fixed_points/pck.ads
> +++ b/gdb/testsuite/gdb.ada/fixed_points/pck.ads
> @@ -30,6 +30,10 @@ package Pck is
>        with Small => Delta4 / 3.0;
>     FP4_Var : FP4_Type := 2 * Delta4;
>  
> +   Delta5 : constant := 0.000_000_000_000_000_000_1;
> +   type FP5_Type is delta Delta5 range 0.0 .. Delta5 * 10
> +      with Small => Delta5 / 3.0;
> +
>     procedure Do_Nothing (A : System.Address);
>  end pck;
>  
> -- 
> 2.26.2

-- 
Joel


More information about the Gdb-patches mailing list