From patchwork Fri May 3 18:21:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 32499 Received: (qmail 101720 invoked by alias); 3 May 2019 18:21:26 -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 101707 invoked by uid 89); 3 May 2019 18:21:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=System.Address, foo.adb, UD:Address, systemaddress X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 03 May 2019 18:21:24 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 5A649116C95; Fri, 3 May 2019 14:21:23 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id mfJwQ8fYLJ8c; Fri, 3 May 2019 14:21:23 -0400 (EDT) Received: from murgatroyd.Home (97-122-168-123.hlrn.qwest.net [97.122.168.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPSA id 03512116530; Fri, 3 May 2019 14:21:22 -0400 (EDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Fix cast of character to enum type in Ada Date: Fri, 3 May 2019 12:21:20 -0600 Message-Id: <20190503182120.11052-1-tromey@adacore.com> MIME-Version: 1.0 An internal bug report points out that, when a global character enum type is used, casting fails, like: (gdb) print global_char_enum'('F') $1 = 70 The bug here turns out to be that enumerators are qualified, so for example the mangled name might be "pck__QU48", rather than "QU48". This patch fixes the problem by only examining the suffix of the enumerator. This is ok because the type is already known, and because the mangling scheme ensures that there won't be clashes. Tested on x86-64 Fedora 29. gdb/ChangeLog 2019-05-03 Tom Tromey * ada-exp.y (convert_char_literal): Check suffix of each enumerator. gdb/testsuite/ChangeLog 2019-05-03 Tom Tromey * gdb.ada/char_enum/pck.ads (Global_Enum_Type): New type. * gdb.ada/char_enum/foo.adb: Use Global_Enum_Type. * gdb.ada/char_enum.exp: Add test. --- gdb/ChangeLog | 5 +++++ gdb/ada-exp.y | 10 +++++++++- gdb/testsuite/ChangeLog | 6 ++++++ gdb/testsuite/gdb.ada/char_enum.exp | 3 +-- gdb/testsuite/gdb.ada/char_enum/foo.adb | 1 + gdb/testsuite/gdb.ada/char_enum/pck.ads | 1 + 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index efad85b19ad..2a53d49ac8f 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -1408,9 +1408,17 @@ convert_char_literal (struct type *type, LONGEST val) return val; xsnprintf (name, sizeof (name), "QU%02x", (int) val); + size_t len = strlen (name); for (f = 0; f < TYPE_NFIELDS (type); f += 1) { - if (strcmp (name, TYPE_FIELD_NAME (type, f)) == 0) + /* Check the suffix because an enum constant in a package will + have a name like "pkg__QUxx". This is safe enough because we + already have the correct type, and because mangling means + there can't be clashes. */ + const char *ename = TYPE_FIELD_NAME (type, f); + size_t elen = strlen (ename); + + if (elen >= len && strcmp (name, ename + elen - len) == 0) return TYPE_FIELD_ENUMVAL (type, f); } return val; diff --git a/gdb/testsuite/gdb.ada/char_enum.exp b/gdb/testsuite/gdb.ada/char_enum.exp index 4b35fcb5ac4..c37d696f66d 100644 --- a/gdb/testsuite/gdb.ada/char_enum.exp +++ b/gdb/testsuite/gdb.ada/char_enum.exp @@ -27,5 +27,4 @@ set bp_location [gdb_get_line_number "STOP" ${testdir}/foo.adb] runto "foo.adb:$bp_location" gdb_test "print Char_Enum_Type'('B')" "= 1 'B'" - - +gdb_test "print pck.Global_Enum_Type'('Y')" "= 1 'Y'" diff --git a/gdb/testsuite/gdb.ada/char_enum/foo.adb b/gdb/testsuite/gdb.ada/char_enum/foo.adb index 95914da2cfc..cf7fb7d3399 100644 --- a/gdb/testsuite/gdb.ada/char_enum/foo.adb +++ b/gdb/testsuite/gdb.ada/char_enum/foo.adb @@ -18,6 +18,7 @@ with Pck; use Pck; procedure Foo is type Char_Enum_Type is ('A', 'B', 'C', 'D', 'E'); Char : Char_Enum_Type := 'D'; + Gchar : Global_Enum_Type := 'Z'; begin Do_Nothing (Char'Address); -- STOP end Foo; diff --git a/gdb/testsuite/gdb.ada/char_enum/pck.ads b/gdb/testsuite/gdb.ada/char_enum/pck.ads index 5dd03889dee..f952e1c31c1 100644 --- a/gdb/testsuite/gdb.ada/char_enum/pck.ads +++ b/gdb/testsuite/gdb.ada/char_enum/pck.ads @@ -16,6 +16,7 @@ with System; package Pck is + type Global_Enum_Type is ('X', 'Y', 'Z'); procedure Do_Nothing (A : System.Address); end Pck;