[clang] [clang][CodeGen] Fix crash in CGDebugInfo on incomplete record type (#156352) (PR #197928)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 15 06:13:06 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Vitor Ramos (VitorRamos)
<details>
<summary>Changes</summary>
Fix a crash when generating debug info for a template class that is
still being defined when its forward declaration is needed.
getTypeIdentifier() called getVTableLinkage() on a record that was only
"being defined" (not yet complete), which triggered premature
ASTRecordLayout computation and cached a layout with zero fields. Later,
CollectRecordFields used the stale cached layout and crashed on an
out-of-bounds field offset access.
Replace getDefinition() with isCompleteDefinition() to correctly skip
records whose definition is not yet complete.
Fixes #<!-- -->156352
---
Full diff: https://github.com/llvm/llvm-project/pull/197928.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+1-1)
- (added) clang/test/CodeGenCXX/debug-info-template-incomplete-record.cpp (+83)
``````````diff
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 578d09f7971d6..71a21f19fbd5b 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1290,7 +1290,7 @@ static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM,
if (!needsTypeIdentifier(TD, CGM, TheCU))
return Identifier;
if (const auto *RD = dyn_cast<CXXRecordDecl>(TD))
- if (RD->getDefinition())
+ if (RD->isCompleteDefinition())
if (RD->isDynamicClass() &&
CGM.getVTableLinkage(RD) == llvm::GlobalValue::ExternalLinkage)
return Identifier;
diff --git a/clang/test/CodeGenCXX/debug-info-template-incomplete-record.cpp b/clang/test/CodeGenCXX/debug-info-template-incomplete-record.cpp
new file mode 100644
index 0000000000000..f81433d53d296
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-template-incomplete-record.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -std=c++20 -debug-info-kind=standalone -fvisibility=hidden \
+// RUN: -O2 -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
+//
+// Verify that we don't crash when generating debug info for a template class
+// that is still being defined when its forward declaration is needed. The bug
+// was that getTypeIdentifier() called getVTableLinkage() on a record that was
+// only "being defined" (not yet complete), which triggered premature
+// ASTRecordLayout computation and cached a layout with zero fields. Later,
+// CollectRecordFields used the stale cached layout and crashed on an
+// out-of-bounds field offset access.
+
+class a;
+template<class>
+class b;
+class c
+{
+public:
+ using d = a;
+};
+template<class>
+class f;
+template<class e>
+class h
+{
+ using j = typename e::j;
+ j k();
+};
+class l;
+class m
+{
+ using i = f<l>;
+ i n();
+};
+template<class>
+class f
+{
+public:
+ using e = l;
+ using o = e;
+ using d = b<e>;
+ d *p;
+};
+class L;
+class q
+{
+public:
+ using j = L;
+};
+class r
+{
+ ~r();
+ h<q> s;
+};
+r::~r() = default;
+class l
+{
+public:
+ using j = m;
+ using g = c;
+};
+class J
+{
+ h<l> t;
+};
+class a
+{
+public:
+ virtual ~a();
+};
+template<class e>
+class b : e::g::d
+{
+ using u = typename f<e>::o;
+ int v;
+};
+class L : J
+{
+};
+extern template class b<l>;
+
+// Just verify we produce debug info for b<l> with its field v.
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "b<l>"
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "v"
``````````
</details>
https://github.com/llvm/llvm-project/pull/197928
More information about the cfe-commits
mailing list