Fix gdb.base/whatis-ptype-typedefs.exp on 32-bit archs
The gdb.base/whatis-ptype-typedefs.exp testcase has several tests that fail on 32-bit architectures. E.g., on 'x86-64 -m32', I see: ... FAIL: gdb.base/whatis-ptype-typedefs.exp: lang=c: cast: whatis (float_typedef) v_uchar_array_t_struct_typedef (invalid) FAIL: gdb.base/whatis-ptype-typedefs.exp: lang=c: cast: ptype (float_typedef) v_uchar_array_t_struct_typedef (invalid) ... gdb.log: (gdb) whatis (float_typedef) v_uchar_array_t_struct_typedef type = float_typedef (gdb) FAIL: gdb.base/whatis-ptype-typedefs.exp: lang=c: cast: whatis (float_typedef) v_uchar_array_t_struct_typedef (invalid) As Simon explained [1], the issue boils down to the fact that on 64-bit, this is an invalid cast: (gdb) p (float_typedef) v_uchar_array_t_struct_typedef Invalid cast. while on 32 bits it is valid: (gdb) p (float_typedef) v_uchar_array_t_struct_typedef $1 = 1.16251721e-41 The expression basically tries to cast an array (which decays to a pointer) to a float. The cast works on 32 bits because a float and a pointer are of the same size, and value_cast works in that case: ~~~ More general than a C cast: accepts any two types of the same length, and if ARG2 is an lvalue it can be cast into anything at all. */ ~~~ On 64 bits, they are not the same size, so it ends throwing the "Invalid cast" error. The testcase is expecting the invalid cast behavior, thus the FAILs. A point of these tests was to cover as many code paths in value_cast as possible, as a sort of documentation of the current behavior: # The main idea here is testing all the different paths in the # value casting code in GDB (value_cast), making sure typedefs are # preserved. ... # We try all combinations, even those that don't parse, or are # invalid, to catch the case of a regression making them # inadvertently valid. For example, these convertions are # invalid: ... In that spirit, this commit makes the testcase adjust itself depending on size of floats and pointers, and also test floats of different sizes. Passes cleanly on x86-64 GNU/Linux both -m64/-m32. [1] - https://sourceware.org/ml/gdb-patches/2017-11/msg00382.html gdb/ChangeLog: 2017-11-20 Pedro Alves <palves@redhat.com> * gdb.base/whatis-ptype-typedefs.c (double_typedef) (long_double_typedef): New typedefs. Use DEF on double and long double. * gdb.base/whatis-ptype-typedefs.exp: Add double and long double cases. (run_tests): New 'float_ptr_same_size', 'double_ptr_same_size', and 'long_double_ptr_same_size' locals. Use them to decide whether cast from array/function to float is valid/invalid.
This commit is contained in:
parent
b77db948f4
commit
73fcf6418d
3 changed files with 57 additions and 3 deletions
|
@ -1,3 +1,14 @@
|
|||
2017-11-20 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* gdb.base/whatis-ptype-typedefs.c (double_typedef)
|
||||
(long_double_typedef): New typedefs.
|
||||
Use DEF on double and long double.
|
||||
* gdb.base/whatis-ptype-typedefs.exp: Add double and long double
|
||||
cases.
|
||||
(run_tests): New 'float_ptr_same_size', 'double_ptr_same_size',
|
||||
and 'long_double_ptr_same_size' locals. Use them to decide
|
||||
whether cast from array/function to float is valid/invalid.
|
||||
|
||||
2017-11-17 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* gdb.rust/traits.rs: New file.
|
||||
|
|
|
@ -56,6 +56,16 @@ DEF (int);
|
|||
typedef float float_typedef;
|
||||
DEF (float);
|
||||
|
||||
/* Double floats. */
|
||||
|
||||
typedef double double_typedef;
|
||||
DEF (double);
|
||||
|
||||
/* Long doubles. */
|
||||
|
||||
typedef long double long_double_typedef;
|
||||
DEF (long_double);
|
||||
|
||||
/* Enums. */
|
||||
|
||||
typedef enum colors {red, green, blue} colors_typedef;
|
||||
|
|
|
@ -92,6 +92,16 @@ set table {
|
|||
{"v_float_typedef" "float_typedef" "float"}
|
||||
{"v_float_typedef2" "float_typedef2" "float"}
|
||||
|
||||
{"double_typedef" "double" "double"}
|
||||
{"double_typedef2" "double_typedef" "double"}
|
||||
{"v_double_typedef" "double_typedef" "double"}
|
||||
{"v_double_typedef2" "double_typedef2" "double"}
|
||||
|
||||
{"long_double_typedef" "long double" "long double"}
|
||||
{"long_double_typedef2" "long_double_typedef" "long double"}
|
||||
{"v_long_double_typedef" "long_double_typedef" "long double"}
|
||||
{"v_long_double_typedef2" "long_double_typedef2" "long double"}
|
||||
|
||||
{"colors_typedef" "(enum )?colors" "enum colors( : unsigned int)? {red, green, blue}"}
|
||||
{"colors_typedef2" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
|
||||
{"v_colors_typedef" "colors_typedef" "enum colors( : unsigned int)? {red, green, blue}"}
|
||||
|
@ -199,6 +209,22 @@ proc run_tests {lang} {
|
|||
}
|
||||
}
|
||||
|
||||
# If floats and pointers have the same size on this architecture,
|
||||
# then casting from array/function to float works, because
|
||||
# arrays/functions first decay to pointers, and then GDB's cast is
|
||||
# more general than a C cast and accepts any two types of the same
|
||||
# length.
|
||||
set float_ptr_same_size \
|
||||
[get_integer_valueof "sizeof (float) == sizeof (void *)" -1]
|
||||
|
||||
# Ditto double.
|
||||
set double_ptr_same_size \
|
||||
[get_integer_valueof "sizeof (double) == sizeof (void *)" -1]
|
||||
|
||||
# Ditto long double.
|
||||
set long_double_ptr_same_size \
|
||||
[get_integer_valueof "sizeof (long double) == sizeof (void *)" -1]
|
||||
|
||||
# Test converting/casting all variables in the first column of the
|
||||
# table to all types (found in the first column of the table).
|
||||
# The aggregates are all defined to be the same size so that
|
||||
|
@ -230,7 +256,7 @@ proc run_tests {lang} {
|
|||
# regression making them inadvertently valid. For
|
||||
# example, these convertions are invalid:
|
||||
#
|
||||
# float <-> array
|
||||
# float <-> array [iff sizeof pointer != sizeof float]
|
||||
# array -> function (not function pointer)
|
||||
# array -> member_ptr
|
||||
#
|
||||
|
@ -247,8 +273,15 @@ proc run_tests {lang} {
|
|||
gdb_test "whatis ($to) $from" "syntax error.*" "whatis ($to) $from (syntax)"
|
||||
gdb_test "ptype ($to) $from" "syntax error.*" "ptype ($to) $from (syntax)"
|
||||
} elseif {([string match "*float*" $from] && [string match "*array*" $to])
|
||||
|| ([string match "float*" $to] && [string match "*array*" $from])
|
||||
|| ([string match "float*" $to] && [string match "*method" $from])
|
||||
|| (!$float_ptr_same_size
|
||||
&& ([string match "float*" $to] && [string match "*array*" $from]
|
||||
|| [string match "float*" $to] && [string match "*method" $from]))
|
||||
|| (!$double_ptr_same_size
|
||||
&& ([string match "double*" $to] && [string match "*array*" $from]
|
||||
|| [string match "double*" $to] && [string match "*method" $from]))
|
||||
|| (!$long_double_ptr_same_size
|
||||
&& ([string match "long_double*" $to] && [string match "*array*" $from]
|
||||
|| [string match "long_double*" $to] && [string match "*method" $from]))
|
||||
|| ([string match "*ftype" $to] && [string match "*array*" $from])
|
||||
|| ([string match "*ftype2" $to] && [string match "*array*" $from])
|
||||
|| ([string match "*ftype" $to] && [string match "*method" $from])
|
||||
|
|
Loading…
Add table
Reference in a new issue