This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[pushed] Fix gdb.base/whatis-ptype-typedefs.exp on 32-bit archs (Re: [PATCH] Fix type casts losing typedefs and reimplement "whatis" typedef stripping)
- From: Pedro Alves <palves at redhat dot com>
- To: Yao Qi <qiyaoltc at gmail dot com>
- Cc: Simon Marchi <simark at simark dot ca>, GDB Patches <gdb-patches at sourceware dot org>, Phil Muldoon <pmuldoon at redhat dot com>, Andreas Schwab <schwab at suse dot de>
- Date: Mon, 20 Nov 2017 23:11:02 +0000
- Subject: [pushed] Fix gdb.base/whatis-ptype-typedefs.exp on 32-bit archs (Re: [PATCH] Fix type casts losing typedefs and reimplement "whatis" typedef stripping)
- Authentication-results: sourceware.org; auth=none
- References: <1498837699-20897-1-git-send-email-palves@redhat.com> <d727c2c0-9e19-9e7e-c1c0-38b3345f0499@redhat.com> <5225ca30-ef69-040d-3f96-be2e5e87b80b@redhat.com> <CAH=s-PMc+bp7rXhwZ0kNdTc5WZ+xL0G1NSE6m3pMM_zFo60b6Q@mail.gmail.com> <4b73fb98-b8c2-9d2f-1981-4660e3c202e6@simark.ca> <67474590-af49-a387-9f8b-044bdd689dc7@redhat.com> <20171120223459.GG318@1170ee0b50d5>
On 11/20/2017 10:34 PM, Yao Qi wrote:
> On 17-11-20 16:42:48, Pedro Alves wrote:
>>
>> So in that spirit, I propose starting my making the testcase adjust
>> itself, like below, and also test floats of different sizes, leaving
>> changing GDB's behavior for a separate consideration/change (using
>> the fixed/extended test as baseline).
>>
>
> I agree. Some tests fail on 32-bit at the point when they were added,
> so tests should match gdb's behaviour. As usual, we can gdb behaviour
> after we are sure the behaviour is incorrect.
>
> Beside Simon's review, patch is good to me.
Thanks guys. Here's what I checked in.
>From 73fcf6418ddce47ead4ffde4fc9fea8e8bd1f4af Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Mon, 20 Nov 2017 23:03:17 +0000
Subject: [PATCH] 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.
---
gdb/testsuite/ChangeLog | 11 +++++++
gdb/testsuite/gdb.base/whatis-ptype-typedefs.c | 10 ++++++
gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp | 39 ++++++++++++++++++++++--
3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 12938e7..fa329b4 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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.
diff --git a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.c b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.c
index 5711a96..35c7279 100644
--- a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.c
+++ b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.c
@@ -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;
diff --git a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp
index d333d81..ea0ef6c 100644
--- a/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp
+++ b/gdb/testsuite/gdb.base/whatis-ptype-typedefs.exp
@@ -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])
--
2.5.5