From patchwork Mon Nov 20 23:11:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 24392 Received: (qmail 65368 invoked by alias); 20 Nov 2017 23:11:11 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 65350 invoked by uid 89); 20 Nov 2017 23:11:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KB_WAM_FROM_NAME_SINGLEWORD, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=Here's, Heres, Beside X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 20 Nov 2017 23:11:09 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E95EF49038; Mon, 20 Nov 2017 23:11:07 +0000 (UTC) Received: from [127.0.0.1] (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id A5D7B60BEC; Mon, 20 Nov 2017 23:11:03 +0000 (UTC) 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) To: Yao Qi References: <1498837699-20897-1-git-send-email-palves@redhat.com> <5225ca30-ef69-040d-3f96-be2e5e87b80b@redhat.com> <4b73fb98-b8c2-9d2f-1981-4660e3c202e6@simark.ca> <67474590-af49-a387-9f8b-044bdd689dc7@redhat.com> <20171120223459.GG318@1170ee0b50d5> Cc: Simon Marchi , GDB Patches , Phil Muldoon , Andreas Schwab From: Pedro Alves Message-ID: Date: Mon, 20 Nov 2017 23:11:02 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <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 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 * 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 + + * 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 * 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])