From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 4chEIXz8Amr1WjMAWB0awg (envelope-from ) for ; Tue, 12 May 2026 06:10:04 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OvwlYET9; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 806661E0C3; Tue, 12 May 2026 06:10:04 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.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 385E21E093 for ; Tue, 12 May 2026 06:10:01 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 549604BAE7F0 for ; Tue, 12 May 2026 10:10:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 549604BAE7F0 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OvwlYET9 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 273544BAD16F for ; Tue, 12 May 2026 10:07:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 273544BAD16F Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 273544BAD16F Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778580468; cv=none; b=DZSSuU1y7O5U4PIDuKt3rZ2IeIWu+xJl3IsukxnJASD4yXDNlev366c2osKYjseooQM81pdEli+oKDuwbJSx12wxJ/DAvc7noa2Q78Y8zuKDCDp3WCOJPhH1x2w1OJjRyOs5sWTsQ77M/SrD7KOKLnml/Cqvfm3uxv5r2tD21/w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1778580468; c=relaxed/simple; bh=l4vLjVX2lF9U+5uTYV5Flc/bk/Vyf3p4kPlVb8YX15A=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=cPgOn26k4vUenEN5DBjEaCpXdeIGr4hPAoh0TvCJry/4czys4ZMGhD45siP8i+R68gCZ32osqeHD0L2G9K2BeNTXdowK9eKZFqAdF+ym+eIhekGPBIRQ1D/PTMTpoXi7aqveeoW1bm/NIpe3tNwUnV8A5qMXV+fdwHF7DeOceFk= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OvwlYET9 DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 273544BAD16F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778580467; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JuGP9VGmGVG/FlQp3eyyJO0X9NNCiEEZuXQZP/T588E=; b=OvwlYET9f0TWkF7DIMeQVn0A682q00aP/h1YZPlL52Oec8LeLMK46a2rlhACgAAqA1CQD2 kqSXGFtMOjZYIMjGNAYgh7yjOVKqm9fiJbMRIYS1k+PXe6MOOBcfB5rTO4fhQeLzJ/8ejY 9VJV9HEa1EeqK8+XJRPJpR/hpueODZM= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-365-nEVvlQFyO86UkzsRpotawg-1; Tue, 12 May 2026 06:07:45 -0400 X-MC-Unique: nEVvlQFyO86UkzsRpotawg-1 X-Mimecast-MFC-AGG-ID: nEVvlQFyO86UkzsRpotawg_1778580465 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-44ffa15dc73so4770354f8f.1 for ; Tue, 12 May 2026 03:07:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778580464; x=1779185264; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=JuGP9VGmGVG/FlQp3eyyJO0X9NNCiEEZuXQZP/T588E=; b=b8R7Z3RA/uL6X5Hk4q78NEPDJkb2YadFmoIl8jSuAjwcSbnFScOlgzn3haYet4jPE8 lvbCAnDGieFCLUr/CgYwhQQ8l5ZzMtJIDYXQfDI7DssjCJX3CzuwZJImktwWmse6+9yb GfqIoxvyIqmEO/KJPfQRv3l4sOjOPuX3wLw0J+MTjISW6eDtGzaucg3/sl7Gu9ug11xg RTX0GgwCSHiV326IWX2sZwNbgkKcpLqVjxWCppfBFgvJY7wLt0GkrPDNcxIra+Gzwmvo 3LJO6LIn57jPNJj0WO2EwnwnEDnwcq4Mnia7BORh9dBn8Okcojaa8TZQ8c8nzXvE8Lsn ctHg== X-Gm-Message-State: AOJu0Yx9F/dChTZuzL5NHV2dBvYkd1Xkvus0kUpQDbaaN7GhtrEwio2N 2nsiiMICZ1LIXqqB9kbFf1nIuJ0s5aNWOACHoBpcajRHuFEFkwcgX6Wv1N2meyzSOV8LgND7GcI cihe8IPEkF1AKd9XTIIHW7NN4eOcc4lMqsHaSB7rBIn4c0f0SWadRt8lWXlOCVl9XKTosX921Qt 3NpURExBumy9QkI84GYr85pC2u05a0RNeXOiooVMxL8YHXOts= X-Gm-Gg: Acq92OFHJlvxCiwafjbNC29SHfxs5JBfYhS/ZX9e2b6vWMYppXYbVGsQpVznPuoBTpW njjkWdcgMRCdSkjWeTK0vqwLdmez03MSN9plSDmHSEU6Co5kjs3IXxx0koghZ50vhZoi+p9SrtA Z8HuxDKVuAeWy4XPHniYWJ7nLVBzdf+Cif+FwWCut/0RACCDBWCL484TROVWTM8f0CiDWLWbuFx +OYTN6EpY2MkD9RBMeYVcA4AOYP4A4uHMLbjlsmLIjnY1nh43ATMC4VKqpCaASKnbdlTzeQlIfK kIRbswHXMnI2txAzV4eELHWr1OjXShVD/VIbMMObRhW95958ZBD+LE14vWGCNt3h3GA5YKKTMFV J75Q+u7PxTj/CRt4r X-Received: by 2002:a05:600c:4343:b0:48a:563c:c8c5 with SMTP id 5b1f17b1804b1-48e51e15662mr233486175e9.8.1778580464109; Tue, 12 May 2026 03:07:44 -0700 (PDT) X-Received: by 2002:a05:600c:4343:b0:48a:563c:c8c5 with SMTP id 5b1f17b1804b1-48e51e15662mr233485635e9.8.1778580463407; Tue, 12 May 2026 03:07:43 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48e8e5f00e8sm16058525e9.2.2026.05.12.03.07.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 May 2026 03:07:42 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 6/6] gdb: use value::embedded_offset in check_pieced_synthetic_pointer Date: Tue, 12 May 2026 11:07:27 +0100 Message-Id: <51ce4ffad7667ef14f1d9bd4d7bf2746d410d183.1778579473.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: -6pOugMNmeTct-PzBiqT_TQCt466p2_q7F9A9UVuHtY_1778580465 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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 This commit builds on the previous two commits. You should go and read them both for context. Looking at the users of value::bits_synthetic_pointer, all callers but two are now passing either the offset of a field within the value, or hard-coded zero as they want to ask about the entire value. The two exceptions are in coerce_pieced_ref (in dwarf2/expr.c) and in value_addr (in valops.c) where we still pass value::embedded_offset. The problem is that some of the other callers, where we currently pass just a field offset, might also have a non-zero embedded offset, specifically, the call in cp_print_value_fields is in this category. In cp_print_value_fields we are printing fields from a value which is potentially a base class contained within an instance of a derived class, this will be represented by a non-zero embedded_offset, which is currently not taken into account. Additionally, the two callers that currently pass the value::embedded_offset don't scale the embedded offset from bytes to bits. The failure to scale from bytes to bits is interesting, I originally tried to create some tests that exposed this, but constantly failed. It turns out, that in both these locations, in all code paths that I could find, the value::embedded_offset will always be zero. For example in coerce_pieced_ref, a reference cannot be a base class, and so we never expect to see a non-zero embedded_offset in this case. Similarly, in value_addr, the use of value::bits_synthetic_pointer is within a block that only applies to reference types, which means the embedded_offset will be zero. Now within check_pieced_synthetic_pointer we already add the value::offset into the bit_offset which is passed in. Remember, after the previous two commits, the incoming bit_offset is (almost) always the offset of a field within the value. The almost here is the two cases mentioned above. I propose that within check_pieced_synthetic_pointer we should take into account both value::offset and value::embedded_offset. Then the two cases that currently pass value::embedded_offset can be changed to just pass zero. With this done, and the previous two commits, we now have a consistent model. value::bits_synthetic_pointer expects the (bit) offset of a field within the value to check. In many cases this will be zero meaning we want to check from the start of the value, but in some cases it can be non-zero. Then within value::bits_synthetic_pointer implementations, like check_pieced_synthetic_pointer, we will take the value::offset and value::embedded_offset into account, remembering to scale them from bytes to bits. I have also changed indirect_pieced_value to also take the embedded_offset into account. I have done this for consistency rather than necessity. I believe that the embedded_offset will always be zero within indirect_pieced_value. The indirect_pieced_value function is only called from value_ind (in valops.c), and only operates on TYPE_CODE_PTR types (checked for in indirect_pieced_value). As a TYPE_CODE_PTR cannot be the base class for a derived type, then we don't expect to ever see a TYPE_CODE_PTR value with a non-zero embedded_offset. But, having indirect_pieced_value take the embedded offset into account is simple enough, and future proofs the code. The gdb.dwarf2/multi-piece-inherited-bitfield.exp test fails without this patch, this exposes the case where the embedded_offset is non-zero and we were previously failing to take this into account. The gdb.dwarf2/multi-piece-primitive-field.exp test was something I wrote while trying to exercise the coerce_pieced_ref code path some more. It is an inheritance based version of the existing test, I was wondering if this would result in a value with a non-zero embedded_offset, but due to how the fields are extracted from the aggregate prior to calling coerce_pieced_ref the embedded_offset is always zero in this function. --- gdb/dwarf2/expr.c | 9 +- .../multi-piece-inherited-bitfield.c | 25 +++ .../multi-piece-inherited-bitfield.exp | 151 ++++++++++++++++++ .../multi-piece-primitive-field.exp | 62 ++++++- gdb/valops.c | 3 +- 5 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.c create mode 100644 gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.exp diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index a554dd2c880..8b0de78887f 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -502,7 +502,8 @@ check_pieced_synthetic_pointer (const value *value, LONGEST bit_offset, piece_closure *c = (piece_closure *) value->computed_closure (); int i; - bit_offset += TARGET_CHAR_BIT * value->offset (); + bit_offset += (TARGET_CHAR_BIT + * (value->offset () + value->embedded_offset ())); if (value->bitsize ()) bit_offset += value->bitpos (); @@ -548,7 +549,8 @@ indirect_pieced_value (value *value) return NULL; int bit_length = TARGET_CHAR_BIT * type->length (); - LONGEST bit_offset = TARGET_CHAR_BIT * value->offset (); + LONGEST bit_offset + = (TARGET_CHAR_BIT * (value->offset () + value->embedded_offset ())); if (value->bitsize ()) bit_offset += value->bitpos (); @@ -612,8 +614,7 @@ coerce_pieced_ref (const value *value) { struct type *type = check_typedef (value->type ()); - if (value->bits_synthetic_pointer (value->embedded_offset (), - TARGET_CHAR_BIT * type->length ())) + if (value->bits_synthetic_pointer (0, TARGET_CHAR_BIT * type->length ())) { const piece_closure *closure = (piece_closure *) value->computed_closure (); diff --git a/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.c b/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.c new file mode 100644 index 00000000000..7ec6b26af49 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2026 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 . */ + +int target_var = 42; + +int +main (void) +{ + asm ("main_label: .globl main_label"); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.exp b/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.exp new file mode 100644 index 00000000000..427828f7178 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/multi-piece-inherited-bitfield.exp @@ -0,0 +1,151 @@ +# 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 . + +# Setup a derived struct that uses multiple inheritance and is described +# by a multi-piece DWARF location. The second base class contains a +# bitfield member. At one time, printing such a struct would incorrectly +# display the bitfield as . +# +# The cause was that check_pieced_synthetic_pointer (dwarf2/expr.c) +# computes the bit offset as 8 * value->offset() but does not add +# 8 * value->embedded_offset(). When a base subobject is extracted via +# primitive_field, it gets a non-zero embedded_offset but offset remains +# zero. check_pieced_synthetic_pointer then checks piece 0 instead of +# the correct piece, and if piece 0 happens to be an implicit pointer, +# it incorrectly reports the bitfield as a synthetic pointer. + +require allow_cplus_tests + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile .c .S + +set asm_file [standard_output_file ${srcfile2}] + +# First compile the C file only, so we can query some type sizes. +if {[prepare_for_testing "failed to prepare" ${testfile} ${srcfile}]} { + return +} + +Dwarf::assemble ${asm_file} { + cu {} { + DW_TAG_compile_unit { + DW_AT_language @DW_LANG_C_plus_plus + } { + declare_labels char_label int_label first_label second_label \ + derived_label target_label + set int_size [get_sizeof "int" -1] + + char_label: DW_TAG_base_type { + DW_AT_byte_size 1 DW_FORM_udata + DW_AT_encoding @DW_ATE_unsigned_char + DW_AT_name "char" + } + + int_label: DW_TAG_base_type { + DW_AT_byte_size ${int_size} DW_FORM_udata + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" + } + + first_label: DW_TAG_structure_type { + DW_AT_name "First" + DW_AT_byte_size 1 DW_FORM_udata + } { + DW_TAG_member { + DW_AT_name "a" + DW_AT_type :${char_label} + DW_AT_data_member_location 0 DW_FORM_udata + } + } + + second_label: DW_TAG_structure_type { + DW_AT_name "Second" + DW_AT_byte_size 1 DW_FORM_udata + } { + DW_TAG_member { + DW_AT_name "bf" + DW_AT_type :${int_label} + DW_AT_data_member_location 0 DW_FORM_udata + DW_AT_bit_size 8 DW_FORM_udata + } + } + + derived_label: DW_TAG_structure_type { + DW_AT_name "Derived" + DW_AT_byte_size 2 DW_FORM_udata + } { + DW_TAG_inheritance { + DW_AT_type :${first_label} + DW_AT_data_member_location 0 DW_FORM_udata + } + + DW_TAG_inheritance { + DW_AT_type :${second_label} + DW_AT_data_member_location 1 DW_FORM_udata + } + } + + target_label: DW_TAG_variable { + DW_AT_name "target_var" + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + DW_AT_location { + DW_OP_addr [gdb_target_symbol "target_var"] + } SPECIAL_expr + } + + DW_TAG_subprogram { + MACRO_AT_func { "main" } + DW_AT_type :${int_label} + DW_AT_external 1 DW_FORM_flag + } { + DW_TAG_variable { + DW_AT_name "d" + DW_AT_type :${derived_label} + DW_AT_location { + DW_OP_GNU_implicit_pointer $target_label 0 + DW_OP_piece 1 + DW_OP_const1u 42 + DW_OP_stack_value + DW_OP_piece 1 + } SPECIAL_expr + } + } + } + } +} + +# Now compile both C source and generated DWARF assembly. +if {[prepare_for_testing "failed to prepare" ${testfile} \ + [list ${asm_file} ${srcfile}] {}]} { + return +} + +# Start the inferior so that 'd' is in scope. +if {![runto_main]} { + return +} + +# With the bug in check_pieced_synthetic_pointer, the bitfield bf in the +# Second base subobject is incorrectly reported as . +# This happens because check_pieced_synthetic_pointer does not account for +# embedded_offset, so it checks piece 0 (the implicit pointer covering +# First) instead of piece 1 (the stack value covering Second). +gdb_test "print d" " = { = {a = }, = {bf = 42}, }" \ + "bitfield in base subobject is not synthetic pointer" diff --git a/gdb/testsuite/gdb.dwarf2/multi-piece-primitive-field.exp b/gdb/testsuite/gdb.dwarf2/multi-piece-primitive-field.exp index 6349d43d67e..4d6b3fcb6c1 100644 --- a/gdb/testsuite/gdb.dwarf2/multi-piece-primitive-field.exp +++ b/gdb/testsuite/gdb.dwarf2/multi-piece-primitive-field.exp @@ -47,7 +47,8 @@ Dwarf::assemble ${asm_file} { DW_TAG_compile_unit { DW_AT_language @DW_LANG_C_plus_plus } { - declare_labels int_label struct_label ref_type_label target_label + declare_labels int_label struct_label ref_type_label target_label \ + first_label second_label derived_label set int_size [get_sizeof "int" -1] set addr_size [get_sizeof "void *" -1] set struct_size [expr {$int_size + $addr_size}] @@ -80,6 +81,43 @@ Dwarf::assemble ${asm_file} { } } + first_label: DW_TAG_structure_type { + DW_AT_name "first" + DW_AT_byte_size ${int_size} DW_FORM_udata + } { + DW_TAG_member { + DW_AT_name "x" + DW_AT_type :${int_label} + DW_AT_data_member_location 0 DW_FORM_udata + } + } + + second_label: DW_TAG_structure_type { + DW_AT_name "second" + DW_AT_byte_size ${addr_size} DW_FORM_udata + } { + DW_TAG_member { + DW_AT_name "ref" + DW_AT_type :${ref_type_label} + DW_AT_data_member_location 0 DW_FORM_udata + } + } + + derived_label: DW_TAG_structure_type { + DW_AT_name "derived" + DW_AT_byte_size ${struct_size} DW_FORM_udata + } { + DW_TAG_inheritance { + DW_AT_type :${first_label} + DW_AT_data_member_location 0 DW_FORM_udata + } + + DW_TAG_inheritance { + DW_AT_type :${second_label} + DW_AT_data_member_location ${int_size} DW_FORM_udata + } + } + target_label: DW_TAG_variable { DW_AT_name "target_var" DW_AT_type :${int_label} @@ -105,6 +143,18 @@ Dwarf::assemble ${asm_file} { DW_OP_piece $addr_size } SPECIAL_expr } + + DW_TAG_variable { + DW_AT_name "d" + DW_AT_type :${derived_label} + DW_AT_location { + DW_OP_const4u 456 + DW_OP_stack_value + DW_OP_piece $int_size + DW_OP_GNU_implicit_pointer $target_label 0 + DW_OP_piece $addr_size + } SPECIAL_expr + } } } } @@ -128,3 +178,13 @@ gdb_test "print s" " = {x = 123, ref = @$hex}" \ gdb_test "print s.ref" " = \\(int &\\) @$hex: 42" \ "print ref member of multi-piece struct" + +# Same test but with inheritance. The reference field is in the +# second base class, so it reaches coerce_pieced_ref through a +# different path to the above case. +gdb_test "print d" \ + " = { = {x = 456}, = {ref = @$hex}, }" \ + "print inherited multi-piece struct with implicit pointer ref" + +gdb_test "print d.ref" " = \\(int &\\) @$hex: 42" \ + "print ref member of inherited multi-piece struct" diff --git a/gdb/valops.c b/gdb/valops.c index c8b27868a8c..ab6fd5079e1 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1545,8 +1545,7 @@ value_addr (struct value *arg1) if (TYPE_IS_REFERENCE (type)) { - if (arg1->bits_synthetic_pointer (arg1->embedded_offset (), - TARGET_CHAR_BIT * type->length ())) + if (arg1->bits_synthetic_pointer (0, TARGET_CHAR_BIT * type->length ())) arg1 = coerce_ref (arg1); else { -- 2.25.4