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
