[gcc r17-3278] debug/126355 - preserve debug info for IPA ICF wrappers

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:b6477e6c4efd6df2719190cb048cf300ff31af46

commit r17-3278-gb6477e6c4efd6df2719190cb048cf300ff31af46
Author: Longjun Luo <[email protected]>
Date:   Thu Jul 23 00:01:50 2026 +0800

    debug/126355 - preserve debug info for IPA ICF wrappers
    
    When IPA ICF keeps a distinct symbol for an address-taken function by
    replacing its body with a wrapper, cgraph_node::create_wrapper reuses the
    original function declaration and its early debug DIE.
    
    create_wrapper then calls expand_thunk with force_gimple_thunk set.  Forced
    GIMPLE thunks are normally created after early debug, so expand_thunk marks
    their declarations ignored.  For an ICF wrapper this also prevents final
    debug emission from attaching the wrapper address to the existing DIE.
    The wrapper consequently has code and an STT_FUNC symbol but no
    address-bearing DW_TAG_subprogram DIE.
    
    Preserve the declaration's original DECL_IGNORED_P value across forced
    GIMPLE thunk expansion in create_wrapper.  Declarations that were already
    ignored remain ignored, while an original source declaration can receive
    its final address information.
    
    Tested on x86_64-pc-linux-gnu with the new gcc.dg/debug/dwarf2 test.  The
    test fails before the change and passes afterwards.
    
            PR debug/126355
    
    gcc/ChangeLog:
    
            * cgraphunit.cc (cgraph_node::create_wrapper): Preserve
            DECL_IGNORED_P across forced GIMPLE thunk expansion.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/debug/dwarf2/pr126355.c: New test.
    
    Signed-off-by: Longjun Luo <[email protected]>

Diff:
---
 gcc/cgraphunit.cc                            |  5 ++++
 gcc/testsuite/gcc.dg/debug/dwarf2/pr126355.c | 35 ++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 67aaebf108b0..d397c9ae4cc0 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -2683,7 +2683,12 @@ cgraph_node::create_wrapper (cgraph_node *target)
       arguments = TREE_CHAIN (arguments);
     }
 
+  /* Forced GIMPLE thunks are normally ignored because they are created
+     after early debug.  ICF wrappers retain the original function decl and
+     its early DIE, so preserve its original debug state.  */
+  bool ignored_p = DECL_IGNORED_P (decl);
   expand_thunk (this, false, true);
+  DECL_IGNORED_P (decl) = ignored_p;
   thunk_info::remove (this);
 
   /* Inline summary set-up.  */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr126355.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr126355.c
new file mode 100644
index 000000000000..35e321008aa9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr126355.c
@@ -0,0 +1,35 @@
+/* PR debug/126355 */
+/* Verify that an IPA ICF wrapper for an address-taken function keeps an
+   address-bearing subprogram DIE.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -gdwarf -dA -fdump-ipa-icf-details" } */
+
+int
+pr_icf_wrapper_a (const char *host)
+{
+  (void) host;
+  return 0;
+}
+
+int
+pr_icf_wrapper_b (const char *host)
+{
+  (void) host;
+  return 0;
+}
+
+int (*keep_a) (const char *) = pr_icf_wrapper_a;
+int (*keep_b) (const char *) = pr_icf_wrapper_b;
+
+int
+main (int argc, char **argv)
+{
+  const char *arg = argc > 1 ? argv[1] : "x";
+  return keep_a (arg) + keep_b (arg);
+}
+
+/* Check the ICF direction explicitly because the DWARF scan below inspects
+   pr_icf_wrapper_b, the wrapper.  */
+/* { dg-final { scan-ipa-dump "Semantic equality hit:pr_icf_wrapper_a/\[0-9+\]+->pr_icf_wrapper_b/\[0-9+\]+" "icf" } } */
+/* { dg-final { scan-ipa-dump "Wrapper has been created" "icf" } } */
+/* { dg-final { scan-assembler "\\(DIE \\(0x\[0-9a-f\]+\\) DW_TAG_subprogram\\)\[\r\n\]+(\[^\r\n\]*\[\r\n\]+){1,12}\[^\r\n\]*DW_AT_name: \"pr_icf_wrapper_b\"\[\r\n\]+(\[^\r\n\]*\[\r\n\]+){1,12}\[^\r\n\]*DW_AT_low_pc" } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.