Author: Vladislav Dzhidzhoev
Date: 2025-11-17T13:10:54+01:00
New Revision: 82ba3f5d316c102aad1b0721d64c028a8724a3a4

URL: 
https://github.com/llvm/llvm-project/commit/82ba3f5d316c102aad1b0721d64c028a8724a3a4
DIFF: 
https://github.com/llvm/llvm-project/commit/82ba3f5d316c102aad1b0721d64c028a8724a3a4.diff

LOG: [clang][DebugInfo] Clear retained nodes list of vararg trunk's 
DISubprogram (#167758)

This fixes the issue reported in
https://github.com/llvm/llvm-project/pull/166855#issuecomment-3518604073
that had been revealed after
https://github.com/llvm/llvm-project/pull/166855 was merged.

`CodeGenFunction::GenerateVarArgsThunk` creates thunks for vararg
functions by cloning and modifying them. It is different from
`CodeGenFunction::generateThunk`, which is used for Itanium ABI.

According to https://reviews.llvm.org/D39396,
`CodeGenFunction::GenerateVarArgsThunk` may be called before metadata
nodes are resolved. So, it tries to avoid remapping DISubprogram and all
metadata nodes it references inside `CloneFunction()` by manually
cloning DISubprogram.

If optimization level is not OptNone, DILocalVariables for a function
are saved in DISubprogram's retainedNodes field. When
`CodeGenFunction::GenerateVarArgsThunk` clones such DISubprogram without
remapping, it produces a subprogram with incorrectly-scoped retained
nodes. It triggers Verifier checks added in
https://github.com/llvm/llvm-project/pull/166855.

To solve that, retained nodes list of a cloned DISubprogram is cleared.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGVTables.cpp
    clang/test/CodeGenCXX/tmp-md-nodes1.cpp
    clang/test/CodeGenCXX/tmp-md-nodes2.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 00d9f93effb32..c95bd9a3067a9 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -125,6 +125,11 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
   if (!DIS)
     return;
   auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());
+  // As DISubprogram remapping is avoided, clear retained nodes list of
+  // cloned DISubprogram from retained nodes local to original DISubprogram.
+  // FIXME: Thunk function signature is produced wrong in DWARF, as retained
+  // nodes are not remapped.
+  NewDIS->replaceRetainedNodes(llvm::MDTuple::get(Fn->getContext(), {}));
   VMap.MD()[DIS].reset(NewDIS);
 
   // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes

diff  --git a/clang/test/CodeGenCXX/tmp-md-nodes1.cpp 
b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
index 524b2c08c1ad5..f39dca3edaed1 100644
--- a/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
+++ b/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
@@ -2,6 +2,14 @@
 // RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited 
-emit-llvm %s -o - | \
 // RUN: FileCheck %s
 
+// Trigger GenerateVarArgsThunk.
+// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited 
-emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// Check that retainedNodes are properly maintained at function cloning.
+// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited 
-emit-llvm %s -o - | \
+// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI
+
 // This test simply checks that the varargs thunk is created. The failing test
 // case asserts.
 
@@ -16,3 +24,11 @@ struct CharlieImpl : Charlie, Alpha {
 } delta;
 
 // CHECK: define {{.*}} void @_ZThn{{[48]}}_N11CharlieImpl5bravoEz(
+
+// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: 
"_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[RN1:![0-9]+]]
+// A non-empty retainedNodes list of original DISubprogram.
+// CHECK-DI: [[RN1]] = !{!{{.*}}}
+
+// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: 
"_ZN11CharlieImpl5bravoEz", {{.*}}, retainedNodes: [[EMPTY:![0-9]+]]
+// An empty retainedNodes list of cloned DISubprogram.
+// CHECK-DI: [[EMPTY]] = !{}

diff  --git a/clang/test/CodeGenCXX/tmp-md-nodes2.cpp 
b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp
index 8500cf3c42393..0c323ae4f58aa 100644
--- a/clang/test/CodeGenCXX/tmp-md-nodes2.cpp
+++ b/clang/test/CodeGenCXX/tmp-md-nodes2.cpp
@@ -2,6 +2,14 @@
 // RUN: %clang_cc1 -O0 -triple %itanium_abi_triple -debug-info-kind=limited 
-emit-llvm %s -o - | \
 // RUN: FileCheck %s
 
+// Trigger GenerateVarArgsThunk.
+// RUN: %clang_cc1 -O0 -triple riscv64-linux-gnu -debug-info-kind=limited 
-emit-llvm %s -o - | \
+// RUN: FileCheck %s
+
+// Check that retainedNodes are properly maintained at function cloning.
+// RUN: %clang_cc1 -O1 -triple riscv64-linux-gnu -debug-info-kind=limited 
-emit-llvm %s -o - | \
+// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DI
+
 // This test simply checks that the varargs thunk is created. The failing test
 // case asserts.
 
@@ -31,3 +39,11 @@ BOOL CBdVfsImpl::ReqCacheHint( CMsgAgent* p_ma, CACHE_HINT 
hint, ... ) {
 }
 
 // CHECK: define {{.*}} 
@_ZThn{{[48]}}_N10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz(
+
+// An empty retainedNodes list of cloned DISubprogram.
+// CHECK-DI: [[EMPTY:![0-9]+]] = !{}
+// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: 
"_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, 
retainedNodes: [[RN1:![0-9]+]]
+// A non-empty retainedNodes list of original DISubprogram.
+// CHECK-DI: [[RN1]] = !{!{{.*}}}
+
+// CHECK-DI: distinct !DISubprogram({{.*}}, linkageName: 
"_ZN10CBdVfsImpl12ReqCacheHintEP9CMsgAgentN3CFs10CACHE_HINTEz", {{.*}}, 
retainedNodes: [[EMPTY]]


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to