https://gcc.gnu.org/g:d5f30b7d5285679805796461beeb2f7ce4b25c44

commit r16-4753-gd5f30b7d5285679805796461beeb2f7ce4b25c44
Author: David Faust <[email protected]>
Date:   Wed Oct 29 15:21:16 2025 -0700

    btf: do not prune at typedefs
    
    The existing BTF pruning logic meant that an anonymous struct or
    union type hidden behind a typedef, such as in the common construct:
    
      typedef struct { ... } my_struct_type;
    
    could be pruned if 'my_struct_type' was only ever referenced via pointer
    members in other structs/unions types used in the program.
    
    The result of pruning is to skip emitting full type information for
    a struct or union type by replacing it with a BTF_KIND_FWD, indicating
    that it exists but its definition is omitted.  Any types used only by
    pruned types are fully omitted from the generated BTF.
    
    In cases like this where the struct/union type is anonymous, the result
    is an anonymous BTF_KIND_FWD, which is useless.  The presence of such a
    type record rightly causes complaints from BTF loaders.  Worse, since
    the TYPEDEF for 'my_struct_type' itself may _not_ be pruned, its type
    information will be incomplete.
    
    Change the BTF pruner so that we never consider pruning at a typedef,
    and always either keep or discard both the type and the typedef.
    
    gcc/
    
            * btfout.cc (btf_add_used_type_1): Do not consider creating
            fixups at typedefs.
    
    gcc/testsuite/
    
            * gcc.dg/debug/btf/btf-prune-4.c: New.

Diff:
---
 gcc/btfout.cc                                |  3 +-
 gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c | 61 ++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 5a210cd51e6c..eb794ff86944 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1138,7 +1138,8 @@ btf_add_used_type_1 (ctf_container_ref ctfc, 
ctf_dtdef_ref dtd,
 
        /* Try to avoid chasing pointers to struct/union types if the
           underlying type isn't used.  */
-       if (check_ptr && seen_ptr && create_fixups)
+       if (check_ptr && seen_ptr && create_fixups
+           && kind != BTF_KIND_TYPEDEF)
          {
            ctf_dtdef_ref ref = dtd->ref_type;
            uint32_t ref_kind = btf_dtd_kind (ref);
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
new file mode 100644
index 000000000000..3f1955938128
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-prune-4.c
@@ -0,0 +1,61 @@
+/* Test that -gprune-btf does not prune at typedefs.  */
+
+/* { dg-do compile } */
+/* { dg-options "-gbtf -gprune-btf -dA" } */
+
+/* We must have the full definitions of td1 and td3.  Neither are pruned.
+   td2 will be skipped entirely, only because the only reference to
+   it is through struct inner, which is pruned because inner itself
+   is only used as a pointer member.
+
+   In general, we must never get an anonymous FWD; the only FWD in this
+   case will be for 'inner' */
+
+/* Exactly 1 FWD for inner and no anonymous FWD.  */
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_FWD" 1 } } */
+/* { dg-final { scan-assembler-not   "TYPE \[0-9\]+ BTF_KIND_FWD ''" } } */
+/* { dg-final { scan-assembler       " BTF_KIND_FWD 'inner'" } } */
+
+/* One anonymous struct for td1 and one anonymous union for td3.  */
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_STRUCT ''" 1 } } 
*/
+/* { dg-final { scan-assembler-times "TYPE \[0-9\]+ BTF_KIND_UNION ''" 1 } } */
+
+/* The two remaining typedefs.  */
+/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td1'" } } */
+/* { dg-final { scan-assembler " BTF_KIND_TYPEDEF 'td3'" } } */
+
+typedef struct {
+  int x;
+  char c;
+} td1;
+
+typedef struct {
+  long l;
+  char b[4];
+} td2;
+
+typedef union {
+  long l;
+  unsigned short s[2];
+} td3;
+
+struct inner {
+  char a;
+  td2 *ptd;
+  long z;
+};
+
+struct A {
+  td1 *pt;
+  struct inner *in;
+  unsigned long l[4];
+};
+
+struct A foo;
+
+struct B {
+  int x;
+  td3 **ppptd3;
+};
+
+struct B bar;

Reply via email to