llvm-project/clang/test/CodeGenCXX/tmp-md-nodes1.cpp
Vladislav Dzhidzhoev 82ba3f5d31
[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.
2025-11-17 13:10:54 +01:00

35 lines
1.2 KiB
C++

// REQUIRES: asserts
// 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.
struct Alpha {
virtual void bravo(...);
};
struct Charlie {
virtual ~Charlie() {}
};
struct CharlieImpl : Charlie, Alpha {
void bravo(...) {}
} 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]] = !{}