From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ytxxAvpIj2qlVQQAWB0awg (envelope-from ) for ; Wed, 26 Aug 2026 16:13:46 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=LzyOF5SH; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id E271E1E0A3; Wed, 26 Aug 2026 16:13:45 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id AB0571E033 for ; Wed, 26 Aug 2026 16:13:44 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CCFAB4BA798B for ; Wed, 26 Aug 2026 20:13:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CCFAB4BA798B Authentication-Results: sourceware.org; dkim=pass (2048-bit key, secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=LzyOF5SH Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) by sourceware.org (Postfix) with ESMTPS id 444AD4BA2E31 for ; Wed, 26 Aug 2026 20:13:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 444AD4BA2E31 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 444AD4BA2E31 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::329 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787775196; cv=none; b=CIhaxBs4KfnzM458w1DrLPLVzlify7SBLjhBM+pfDjqUwENu4W7WGNedcw9EUP9deUtVDyLMEpZ6FZdCcfgpY+zHhTNU9Rod0PtdpQBySmkTZYDX+Buaf6p/lVWjjq40VrUkNRAXJJeDZ/IdWZBSaw9H1se3phXUA9/hZA4KG2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1787775196; c=relaxed/simple; bh=jxbN0R8DgoxO38lSZFYlNMK83nYLD8rttioFAOvk51M=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=O/2GqwA70sO3yNDAPlMMjv6rN8Kt5GgeyvZTr3M9dkY+Ux+lilPymwoTQ3vvPBvX3eOraVhS4k5sATl2jg/cYghGapGgrtiGAN2Bdcx1S93iMck/YOwwayQbhY9Y/qNhwW+1GUGwbMXEhGOyoCKgitnufrqM4W9h7QRoA7sjSYQ= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (2048-bit key, secure) header.d=adacore.com header.i=@adacore.com header.a=rsa-sha256 header.s=google header.b=LzyOF5SH DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 444AD4BA2E31 Received: by mail-ot1-x329.google.com with SMTP id 46e09a7af769-7f4d9d9d8bbso177351a34.3 for ; Wed, 26 Aug 2026 13:13:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1787775195; x=1788379995; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=bpff7mt0qcMKOsozY8Uo0QOqoGlyot3sQ8fm6mVQbBU=; b=LzyOF5SHXxAbZfsOLAfjSYdEyfuWFtFpxyAYrEmmOcmPXxzP6bFbcoRtr5+kYEUwvy /mhw90uews2W8j3w3mMdhJmzMDhTCRcRb9VU4JZjezP+ZV6dE37u1sRJdV3ZJkYJzA0b OZZZsu2PEToypGqcJsTNy4MWUnJItbDE8VGR4gTnvnOsy+oB+gpXE3rpRSUytm4wchhG zUlcQZnpU/FRA+u9Orj5ckbhNC4nvkiwM1DGRIotAoxQ+0e0HtGxkIKPfoBiJr0jcnej EH4rro9Zmk5n3fKemeIbYwy7ojeYmPW8jC3W9G/IFL9BbzfiKz0HV2rZ6rNSRqOdVVKM zqRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787775195; x=1788379995; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bpff7mt0qcMKOsozY8Uo0QOqoGlyot3sQ8fm6mVQbBU=; b=J6XV+NK7JVwdYqEctpyQpKxT3lr771AuRUezHcEMO+aYJccWa1I3wxK1qxbGzXbVgL dyErEconi4NbP9/KCrA+wUHwmq/2YT5Lcqifs4jw+pe/Gs0jSb+6ZaiKeIooyx1bgZnQ BMzRAQtwtYAADjATfwJXvDgQNuyW0+LN6UeOWpA9Sr5kXPa+ZWCbLkZYZOOZTAJz40n8 9i7YmuR8SlgFmbFW/e6rehYxHyFi3CwHSJPVCmrALrKaANDeg++GkFRTxHsQvVOTgVXC tAflsVw1Vkjz9TGe+MgREL5Bqabhca3aWhjnO8kBt5mBvf5xfdRRvsKv4iHE0O4tSIdI VzSg== X-Gm-Message-State: AFuF++nBkWek43sin39XgKe/+23jGOvw3r+W990Dv8peh/JBtGSmh2x3 n0Uwvn8IbnH631XMqq0IHgBJ8SJ46pKRw0u2dlGG6CflYEL1Z9gpwVYMIPc19rM2beG0Y98iDB0 Cn38= X-Gm-Gg: AR+sD11Hk60s+5NKU3ehbj8A42WH5L8yvrF3kZ+h2dEZGbRo/cFjkktKF7vhKYL3dtS BDbQFkF84spmotGY3kzWRpBbq9kdywtPBbFc7lqnRWPA1OAovghtGcM4oV3+XCR0udN7JB1J973 oAFIauuvIVjURGCKn62HJEPU4wqBffjl6Hbzlo8aPcbM5/io61Hc6QIcQZv2mP0oB45gF4r7A5v CN33E5Qyyds09uA0tw227FuPxSUzXDE2CYTvOFW8tTFfBEWQ5RBQ2vT8Xzc8F0qSukrCbUFVwPm h5787rFXlfeygC29ul9+jJZcqhFS57ycIUe/+qlO8LC51ndcxKTI0eYNAgku7vyZxwlOFhkZEKf Qa9hb4CJN3bDMstCsS9xvy2KXxaxBxUJWxvD7QQb35B+ppffTYjXey4/+VM44zF0lY0OPax2h8L 1u99DMMkqPCbKVOiIr0FGF7q4HQ68ivOUgik3lc8UmUqmR+D+7PvqKMv7NVWQZnBqB3TqTZwwal 2Xt X-Received: by 2002:a05:6830:83af:b0:7f3:ff22:d8 with SMTP id 46e09a7af769-7f4c507f72cmr11641935a34.9.1787775195296; Wed, 26 Aug 2026 13:13:15 -0700 (PDT) Received: from bapiya (97-122-117-2.hlrn.qwest.net. [97.122.117.2]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7f4c83d09d1sm2460654a34.14.2026.08.26.13.13.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 13:13:14 -0700 (PDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH] Check record types for compatibility in ada_type_match Date: Wed, 26 Aug 2026 14:13:12 -0600 Message-ID: <20260826201312.1120857-1-tromey@adacore.com> X-Mailer: git-send-email 2.55.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org While investigating some gdb test suite failures when run against gnat-llvm, I found this oddity in operator_call.exp: (gdb) print p < p Multiple matches for "<" [0] cancel [1] system.dwarf_lines."<" (system.dwarf_lines.search_entry; system.dwarf_lines.search_entry) return boolean at s-dwalin.adb:265 [2] twovecs."<" (twovecs.twovec; twovecs.twovec) return boolean at twovecs.adb:61 While operator_call.exp generally doesn't work yet with gnat-llvm, this particular failure seemed wrong, because the types here aren't even remotely related or compatible -- that is, this call should not be ambiguous. Looking into this, I found that ada_type_match assumes that all record types are identical. I think gdb can do a bit better than this, without trying to implement full Ada overload resolution (which IIUC would require type inferencing as well). In particular we can at least filter out the matches that are wholly unsuitable. That is what this patch does. --- gdb/ada-lang.c | 58 ++++++++++++++- gdb/testsuite/gdb.ada/record-overloads.exp | 70 +++++++++++++++++++ .../gdb.ada/record-overloads/pck.adb | 43 ++++++++++++ .../gdb.ada/record-overloads/pck.ads | 50 +++++++++++++ .../gdb.ada/record-overloads/prog.adb | 32 +++++++++ 5 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.ada/record-overloads.exp create mode 100644 gdb/testsuite/gdb.ada/record-overloads/pck.adb create mode 100644 gdb/testsuite/gdb.ada/record-overloads/pck.ads create mode 100644 gdb/testsuite/gdb.ada/record-overloads/prog.adb diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 174e04af04c..f1aa13fff97 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -4029,6 +4029,57 @@ ada_type_match_arrays (struct type *ftype, struct type *atype) return ada_type_match (f_elt_type, a_elt_type); } +/* Helper for ada_type_match that checks that two record types are + compatible. As with that function, FTYPE is the formal type and + ATYPE is the actual type. + + Note that it is ok if this function is not precise, as long as + there aren't too many false negatives. That is, it's better to + return 'true', because that will result in a menu being presented + to the user. */ + +static bool +ada_type_match_records (type *ftype, type *atype) +{ + /* In the case of tagged types, we look through the parent types; + hence the loop. */ + while (atype != nullptr) + { + if (ftype == atype) + return true; + + /* Note that the formal type might be dynamic in some way. So, + the checks we can do easily are fairly limited. However, in + Ada simply checking the name should be sufficient, because + Ada doesn't allow anonymous record types; nor does it allow + two record types with the same name. And, if this is somehow + violated (through shared library shenanigans or something), + then it's fine to conservatively return 'true'. Note we use + the safe name here, because although Ada doesn't allow + anonymous types, with a little effort the user could arrange + for any type as the actual type. */ + if (streq (ftype->safe_name (), atype->safe_name ())) + return true; + + /* Currently, gdb does not implement dispatching calls, and + class-wide types aren't well-represented in the DWARF anyway. + So as a heuristic, return true if the formal type is a parent + of the actual type. This works out OK because gdb finds the + true runtime type of the actual parameter. + + This could be improved by further examining the overload set + for a best match. However this isn't done today, which is + why the heuristic is needed. */ + if (!ada_is_tagged_type (atype, false)) + break; + + /* If this returns nullptr, the loop will stop. */ + atype = ada_parent_type (atype); + } + + return false; +} + /* Return non-zero if formal type FTYPE matches actual type ATYPE. The term "match" here is rather loose. The match is heuristic and liberal -- while it tries to reject matches that are obviously @@ -4046,6 +4097,10 @@ ada_type_match (struct type *ftype, struct type *atype) if (atype->code () == TYPE_CODE_REF) atype = ada_check_typedef (atype->target_type ()); + /* Also remove aligner types. */ + ftype = ada_aligned_type (ftype); + atype = ada_aligned_type (atype); + switch (ftype->code ()) { default: @@ -4074,7 +4129,8 @@ ada_type_match (struct type *ftype, struct type *atype) case TYPE_CODE_STRUCT: if (!ada_is_array_descriptor_type (ftype)) return (atype->code () == TYPE_CODE_STRUCT - && !ada_is_array_descriptor_type (atype)); + && !ada_is_array_descriptor_type (atype) + && ada_type_match_records (ftype, atype)); [[fallthrough]]; case TYPE_CODE_ARRAY: diff --git a/gdb/testsuite/gdb.ada/record-overloads.exp b/gdb/testsuite/gdb.ada/record-overloads.exp new file mode 100644 index 00000000000..05318cedd30 --- /dev/null +++ b/gdb/testsuite/gdb.ada/record-overloads.exp @@ -0,0 +1,70 @@ +# Copyright 2026 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +load_lib "ada.exp" + +require allow_ada_tests + +standard_ada_testfile prog + +foreach_gnat_encoding scenario flags {all minimal} { + lappend flags debug + + if {[gdb_compile_ada "${srcfile}" "${binfile}-${scenario}" \ + executable $flags] != ""} { + return + } + + clean_restart ${testfile}-${scenario} + + set bp_location [gdb_get_line_number "START" ${testdir}/prog.adb] + runto "prog.adb:$bp_location" + + gdb_test "print oload(r1)" [quotemeta {@DECIMAL = 0}] + gdb_test "print oload(r2)" [quotemeta {@DECIMAL = 1}] + + # This one is not ambiguous. + gdb_test "print oload(rb)" [quotemeta {@DECIMAL = 2}] + + # Neither is this one, because gdb can see that RCB's runtime type + # is Rec_Base. + gdb_test "print oload(rcb)" [quotemeta {@DECIMAL = 2}] + + gdb_test "print oload(rcf)" [quotemeta {@DECIMAL = 4}] + + proc test_menu {var} { + set menu [multi_line "Multiple matches for oload" \ + "\\\[0\\\] cancel" \ + "\\\[1\\\] pck.oload (.*rec_base).*" \ + "\\\[2\\\] pck.oload (.*rec_derived).*" \ + "> $"] + gdb_test_multiple "print oload($var)" "menu for $var" { + -re "$menu" { + pass "$gdb_test_name" + } + default { + fail "$gdb_test_name" + } + } + # Cancel the call. + gdb_test 0 cancelled "cancel call for $var" + } + + # These should not be ambiguous, but currently are: RD because gdb + # can't tell the difference between a type and a class-wide type; + # and RCD because gdb does not implement dispatching. + test_menu rd + test_menu rcd +} diff --git a/gdb/testsuite/gdb.ada/record-overloads/pck.adb b/gdb/testsuite/gdb.ada/record-overloads/pck.adb new file mode 100644 index 00000000000..e4cad65d8b2 --- /dev/null +++ b/gdb/testsuite/gdb.ada/record-overloads/pck.adb @@ -0,0 +1,43 @@ +-- Copyright 2026 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +package body Pck is + + function Oload (C : Rec_1) return Integer is + begin + return 0; + end Oload; + + function Oload (C : Rec_2) return Integer is + begin + return 1; + end Oload; + + function Oload (C : Rec_Base) return Integer is + begin + return 2; + end Oload; + + function Oload (C : Rec_Derived) return Integer is + begin + return 3; + end Oload; + + function Oload (C : Rec_Dyn) return Integer is + begin + return 4; + end Oload; + +end Pck; diff --git a/gdb/testsuite/gdb.ada/record-overloads/pck.ads b/gdb/testsuite/gdb.ada/record-overloads/pck.ads new file mode 100644 index 00000000000..2863637e008 --- /dev/null +++ b/gdb/testsuite/gdb.ada/record-overloads/pck.ads @@ -0,0 +1,50 @@ +-- Copyright 2026 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +package Pck is + + type Rec_1 is record + X : Integer; + end record; + + type Rec_2 is record + X : Integer; + end record; + + function Oload (C : Rec_1) return Integer; + function Oload (C : Rec_2) return Integer; + + type Rec_Base is tagged record + X : Integer; + end record; + + function Oload (C : Rec_Base) return Integer; + + type Rec_Derived is new Rec_Base with null record; + + function Oload (C : Rec_Derived) return Integer; + + type Rec_Dyn (Cond : Boolean := True) is record + case Cond is + when True => + TV : Integer; + when False => + FV : Integer; + end case; + end record; + + function Oload (C : Rec_Dyn) return Integer; + +end Pck; diff --git a/gdb/testsuite/gdb.ada/record-overloads/prog.adb b/gdb/testsuite/gdb.ada/record-overloads/prog.adb new file mode 100644 index 00000000000..2951845ccb0 --- /dev/null +++ b/gdb/testsuite/gdb.ada/record-overloads/prog.adb @@ -0,0 +1,32 @@ +-- Copyright 2026 Free Software Foundation, Inc. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Pck; use Pck; + +procedure Prog is + + R1 : Rec_1 := (X => 23); + R2 : Rec_2 := (X => 23); + RB : Rec_Base := (X => 23); + RD : Rec_Derived := (X => 23); + + RCB : Rec_Base'Class := RB; + RCD : Rec_Base'Class := RD; + + RCF : Rec_Dyn := (Cond => False, FV => 23); + +begin + null; -- START +end Prog; base-commit: 625a5c311e6df32aa28214d017c65303bb5d6451 -- 2.55.0