Skip to content

Commit c537321

Browse files
committed
[lldb] Fix crash when adding members to an "incomplete" type
This fixes a regression caused by delayed type definition searching (llvm#96755 and friends): If we end up adding a member (e.g. a typedef) to a type that we've already attempted to complete (and failed), the resulting AST would end up inconsistent (we would start to "forcibly" complete it, but never finish it), and importing it into an expression AST would crash. This patch fixes this by detecting the situation and finishing the definition as well.
1 parent bb59f04 commit c537321

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,15 @@ static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
269269
}
270270

271271
// We don't have a type definition and/or the import failed, but we need to
272-
// add members to it. Start the definition to make that possible.
273-
tag_decl_ctx->startDefinition();
272+
// add members to it. Start the definition to make that possible. If the type
273+
// has no external storage we also have to complete the definition. Otherwise,
274+
// that will happen when we are asked to complete the type
275+
// (CompleteTypeFromDWARF).
276+
ast.StartTagDeclarationDefinition(type);
277+
if (!tag_decl_ctx->hasExternalLexicalStorage()) {
278+
ast.SetDeclIsForcefullyCompleted(tag_decl_ctx);
279+
ast.CompleteTagDeclarationDefinition(type);
280+
}
274281
}
275282

276283
ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clangxx --target=x86_64-pc-linux -o %t -c %s -g
2+
// RUN: %lldb %t -o "target var a" -o "expr -- var" -o exit | FileCheck %s
3+
4+
// This forces lldb to attempt to complete the type A. Since it has no
5+
// definition it will fail.
6+
// CHECK: target var a
7+
// CHECK: (A) a = <incomplete type "A">
8+
9+
// Now attempt to display the second variable, which will try to add a typedef
10+
// to the incomplete type. Make sure that succeeds. Use the expression command
11+
// to make sure the resulting AST can be imported correctly.
12+
// CHECK: expr -- var
13+
// CHECK: (A::X) $0 = 0
14+
15+
struct A {
16+
// Declare the constructor, but don't define it to avoid emitting the
17+
// definition in the debug info.
18+
A();
19+
using X = int;
20+
};
21+
22+
A a;
23+
A::X var;

0 commit comments

Comments
 (0)