From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id FLcQCuIxyGhHiQUAWB0awg (envelope-from ) for ; Mon, 15 Sep 2025 11:33:54 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=OGtViOZo; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=yeJHidIh; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=OGtViOZo; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=yeJHidIh; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 0C8381E04C; Mon, 15 Sep 2025 11:33:54 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.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,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 server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (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 7902A1E04C for ; Mon, 15 Sep 2025 11:33:52 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D6C793857BB3 for ; Mon, 15 Sep 2025 15:33:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D6C793857BB3 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=OGtViOZo; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=yeJHidIh; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=OGtViOZo; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=yeJHidIh Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.223.131]) by sourceware.org (Postfix) with ESMTPS id A03A33858C83 for ; Mon, 15 Sep 2025 15:33:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A03A33858C83 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A03A33858C83 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=195.135.223.131 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757950394; cv=none; b=Rf+gHNpX2Iwo/rvfAvnogGWsjhd8akOYQDkAbb5OPlEmVSYljC32/qeaxwH593j95ZV4oXw1BnYOFT54K0pK9pwp3LbZScEnQClC7sxEaNDzrbQro4VnTjiB8f/vYQ0iRIFCZ0kWTIhyhQpf6JEszt7hEjqMSDPGjg/YUgAvOc4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1757950394; c=relaxed/simple; bh=yB+4kn6Zu+VQ9lzVlZlzxD2rgLGqs+7WhQf3KRW0zYI=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:From: To:Subject:Date:Message-ID:MIME-Version; b=kOcLf0Ku0lG7ek+zwqwSKexgXs/veUFJoCYgYKi9gQ5lLodgdCWOcv6o6GxAQPPtrdSbb7nwdiiT+Hs39CqgUlpgYtwbIWiDIWl0SbN4Yd500r2OS/dfDPQ5l8zP946BnwTe98yeRvbmubedJ5Gr4vCrzRF/KmhXuhY47lk+ewk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A03A33858C83 Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104:10:150:64:97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 85C121FBAB for ; Mon, 15 Sep 2025 15:33:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1757950393; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7IWVtCioJIUX+OZhhrEo3vcnZZqf+5LUuxvzUejPbHE=; b=OGtViOZoDzug4s/irb8T/VrQAswzUUAcn/Zi1UsAjEa82E9ZWZSMO7MF5mEWToeUMjr4Gr UbIi6Oq2ZNwa9dXnuvAjku5j0RabuuCUUuLyAh+8AThyXVi2NfosjlFnkSrK1rT/fau3ql EvTFjROEb5kFe43+A1AAL/vENnsJaIE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1757950393; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7IWVtCioJIUX+OZhhrEo3vcnZZqf+5LUuxvzUejPbHE=; b=yeJHidIhlpsRtxpzkT6vDudNxyM/bHHCJ+M97bWJLgLI14cXDg/F1leWe7TbxSuYOsc56t AkqmU/6VsNcAJPDA== Authentication-Results: smtp-out2.suse.de; dkim=pass header.d=suse.de header.s=susede2_rsa header.b=OGtViOZo; dkim=pass header.d=suse.de header.s=susede2_ed25519 header.b=yeJHidIh DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1757950393; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7IWVtCioJIUX+OZhhrEo3vcnZZqf+5LUuxvzUejPbHE=; b=OGtViOZoDzug4s/irb8T/VrQAswzUUAcn/Zi1UsAjEa82E9ZWZSMO7MF5mEWToeUMjr4Gr UbIi6Oq2ZNwa9dXnuvAjku5j0RabuuCUUuLyAh+8AThyXVi2NfosjlFnkSrK1rT/fau3ql EvTFjROEb5kFe43+A1AAL/vENnsJaIE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1757950393; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7IWVtCioJIUX+OZhhrEo3vcnZZqf+5LUuxvzUejPbHE=; b=yeJHidIhlpsRtxpzkT6vDudNxyM/bHHCJ+M97bWJLgLI14cXDg/F1leWe7TbxSuYOsc56t AkqmU/6VsNcAJPDA== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 71FCF1368D for ; Mon, 15 Sep 2025 15:33:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id a1mFGrkxyGgheAAAD6G6ig (envelope-from ) for ; Mon, 15 Sep 2025 15:33:13 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH v2] [gdb/symtab] Fix DW_TAG_member regression Date: Mon, 15 Sep 2025 17:33:34 +0200 Message-ID: <20250915153334.18723-1-tdevries@suse.de> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spamd-Result: default: False [-3.01 / 50.00]; BAYES_HAM(-3.00)[100.00%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_MISSING_CHARSET(0.50)[]; R_DKIM_ALLOW(-0.20)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain]; MX_GOOD(-0.01)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCPT_COUNT_ONE(0.00)[1]; ARC_NA(0.00)[]; FUZZY_RATELIMITED(0.00)[rspamd.com]; MIME_TRACE(0.00)[0:+]; RBL_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:104:10:150:64:97:from]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; RCVD_TLS_ALL(0.00)[]; DKIM_TRACE(0.00)[suse.de:+]; RCVD_COUNT_TWO(0.00)[2]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; SPAMHAUS_XBL(0.00)[2a07:de40:b281:104:10:150:64:97:from]; TO_DN_NONE(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; DNSWL_BLOCKED(0.00)[2a07:de40:b281:106:10:150:64:167:received]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER(0.00)[2a07:de40:b281:106:10:150:64:167:received]; DBL_BLOCKED_OPENRESOLVER(0.00)[imap1.dmz-prg2.suse.org:helo, imap1.dmz-prg2.suse.org:rdns, suse.de:mid, suse.de:dkim] X-Rspamd-Queue-Id: 85C121FBAB X-Rspamd-Server: rspamd2.dmz-prg2.suse.org X-Rspamd-Action: no action 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 On openSUSE Leap 15.6 x86_64, with gcc 7 and test-case gdb.base/condbreak-multi-context.exp I run into: ... (gdb) print aaa^M $3 = ^M (gdb) FAIL: $exp: start_before=true: scenario_1: print aaa ... This is a regression since commit 86ac8c54623 ("Convert lookup_symbol_in_objfile"). Likewise in test-cases gdb.cp/m-static.exp and gdb.cp/namespace.exp. The failure is specific to using Dwarf v4: - using target board unix/gdb:debug_flags=-gdwarf-5 fixes it - using target board unix/gdb:debug_flags=-gdwarf-4 on Tumbleweed (with gcc 15 and Dwarf v5 default) triggers it The variable we're trying to print, A::aaa is a static const int member: ... class A : public Base { public: static const int aaa = 10; ... }; ... With Dwarf v5, we have this DIE: ... <2><356>: Abbrev Number: 2 (DW_TAG_variable) <357> DW_AT_name : aaa <35c> DW_AT_linkage_name: _ZN1A3aaaE <364> DW_AT_external : 1 <364> DW_AT_accessibility: 1 (public) <364> DW_AT_declaration : 1 <364> DW_AT_const_value : 10 ... and the cooked index contains these corresponding entries: ... [45] ((cooked_index_entry *) 0x7facf0004730) name: _ZN1A3aaaE canonical: _ZN1A3aaaE qualified: _ZN1A3aaaE DWARF tag: DW_TAG_variable flags: 0x4 [IS_LINKAGE] DIE offset: 0x356 parent: ((cooked_index_entry *) 0) [52] ((cooked_index_entry *) 0x7facf0004700) name: aaa canonical: aaa qualified: A::aaa DWARF tag: DW_TAG_variable flags: 0x0 [] DIE offset: 0x356 parent: ((cooked_index_entry *) 0x7facf00046d0) [A] ... With Dwarf v4, we have instead the following DIE: ... <2><350>: Abbrev Number: 3 (DW_TAG_member) <351> DW_AT_name : aaa <35b> DW_AT_external : 1 <35b> DW_AT_accessibility: 1 (public) <35c> DW_AT_declaration : 1 <35c> DW_AT_const_value : 4 byte block: a 0 0 0 ... and there are no corresponding entries. Fix this by adding an entry: ... [47] ((cooked_index_entry *) 0x7f5a24004660) name: aaa canonical: aaa qualified: A::aaa DWARF tag: DW_TAG_variable flags: 0x0 [] DIE offset: 0x350 parent: ((cooked_index_entry *) 0x7f5a24004630) [A] ... The entry is somewhat unusual because the DW_TAG_variable is used instead of DW_TAG_member, but this approach makes the code handling the cooked index more regular. Add a regression test in the form of a dwarf assembly test-case printing the value of variable A::aaa. In the test-case, for A::aaa, DW_FORM_flag is used to encode DW_AT_declaration. In v1 of this patch that mattered (because of using has_hardcoded_declaration in abbrev_table::read), but that's no longer the case. Nevertheless, also add an A::bbb using FORM_flag_present for DW_AT_declaration. Tested on x86_64-linux. PR symtab/33415 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33415 --- gdb/dwarf2/abbrev.c | 12 +++ gdb/dwarf2/cooked-index-shard.c | 9 ++ gdb/dwarf2/cooked-indexer.c | 3 +- .../gdb.dwarf2/static-const-member.exp | 97 +++++++++++++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.dwarf2/static-const-member.exp diff --git a/gdb/dwarf2/abbrev.c b/gdb/dwarf2/abbrev.c index e3c268e7c47..9f415e0095b 100644 --- a/gdb/dwarf2/abbrev.c +++ b/gdb/dwarf2/abbrev.c @@ -119,6 +119,7 @@ abbrev_table::read (struct dwarf2_section_info *section, bool has_name = false; bool has_linkage_name = false; bool has_external = false; + bool has_const_value = false; /* Now read in declarations. */ int num_attrs = 0; @@ -176,6 +177,10 @@ abbrev_table::read (struct dwarf2_section_info *section, if (is_csize && cur_attr.form == DW_FORM_ref4) sibling_offset = size; break; + + case DW_AT_const_value: + has_const_value = true; + break; } switch (cur_attr.form) @@ -242,6 +247,13 @@ abbrev_table::read (struct dwarf2_section_info *section, the correct scope. */ cur_abbrev->interesting = true; } + else if (cur_abbrev->tag == DW_TAG_member && has_const_value + && has_external) + { + /* For Dwarf v4, GCC generates a DW_TAG_member for a static const + member. */ + cur_abbrev->interesting = true; + } else if (has_hardcoded_declaration && (cur_abbrev->tag != DW_TAG_variable || !has_external)) { diff --git a/gdb/dwarf2/cooked-index-shard.c b/gdb/dwarf2/cooked-index-shard.c index e440d85e1c9..6c115aa4962 100644 --- a/gdb/dwarf2/cooked-index-shard.c +++ b/gdb/dwarf2/cooked-index-shard.c @@ -65,6 +65,15 @@ cooked_index_shard::create (sect_offset die_offset, else if (tag_is_type (tag)) flags |= IS_STATIC; + if (tag == DW_TAG_member) + { + /* A cooked index entry generated for a DW_TAG_member should be treated + the same as one generated for a DW_TAG_variable. Normalize to + DW_TAG_variable, to simplify code dealing with cooked index + entries. */ + tag = DW_TAG_variable; + } + return new (&m_storage) cooked_index_entry (die_offset, tag, flags, lang, name, parent_entry, per_cu); diff --git a/gdb/dwarf2/cooked-indexer.c b/gdb/dwarf2/cooked-indexer.c index 913ff77f890..19361b25517 100644 --- a/gdb/dwarf2/cooked-indexer.c +++ b/gdb/dwarf2/cooked-indexer.c @@ -290,7 +290,8 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu, that is ok. Similarly, we allow an external variable without a location; those are resolved via minimal symbols. */ if (is_declaration && !for_specification - && !(abbrev->tag == DW_TAG_variable && (*flags & IS_STATIC) == 0)) + && !((abbrev->tag == DW_TAG_variable || abbrev->tag == DW_TAG_member) + && (*flags & IS_STATIC) == 0)) { /* We always want to recurse into some types, but we may not want to treat them as definitions. */ diff --git a/gdb/testsuite/gdb.dwarf2/static-const-member.exp b/gdb/testsuite/gdb.dwarf2/static-const-member.exp new file mode 100644 index 00000000000..dbe7a5b9ae0 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/static-const-member.exp @@ -0,0 +1,97 @@ +# Copyright 2025 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 dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile main.c .S + +set asm_file [standard_output_file ${srcfile2}] + +if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile}] } { + return -1 +} + +set int_size [get_sizeof "int" -1] + +Dwarf::assemble ${asm_file} { + cu {} { + DW_TAG_compile_unit { + {DW_AT_language @DW_LANG_C_plus_plus} + } { + declare_labels int_label + + 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"} + } + + DW_TAG_class_type { + {DW_AT_name "A"} + } { + DW_TAG_member { + {DW_AT_name "aaa"} + {DW_AT_type :$int_label} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_declaration 1 DW_FORM_flag} + {DW_AT_accessibility 1 DW_FORM_data1} + {DW_AT_const_value 10 DW_FORM_data1} + } + DW_TAG_member { + {DW_AT_name "bbb"} + {DW_AT_type :$int_label} + {DW_AT_external 1 DW_FORM_flag} + {DW_AT_declaration 1 DW_FORM_flag_present} + {DW_AT_accessibility 1 DW_FORM_data1} + {DW_AT_const_value 11 DW_FORM_data1} + } + } + + DW_TAG_subprogram { + {MACRO_AT_func { "main" }} + {DW_AT_type :${int_label}} + {DW_AT_external 1 DW_FORM_flag} + } { + } + } + } +} + +if { [prepare_for_testing "failed to prepare" $testfile \ + [list $asm_file $srcfile] {nodebug}] } { + return +} + +# Regression test for PR symtab/33415. Print the value of A::aaa in: +# +# class A +# { +# public: +# static const int aaa = 10; +# }; +# +# With DWARF 5, we get a DW_TAG_variable, but with DWARF 4, we get a +# DW_TAG_member instead. + +gdb_test \ + "print A::aaa" \ + " = 10" + +gdb_test \ + "print A::bbb" \ + " = 11" base-commit: 6affec82bd4186aaf2e6733425b1e05870fc0582 -- 2.51.0