This revision was automatically updated to reflect the committed changes.
Closed by commit rG6a7df3a3f940: [ASTImporter][LLDB] Modifying
ImportDeclContext(...) to ensure that we complete… (authored by shafik).
Herald added projects: clang, LLDB.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D71378/new/
https://reviews.llvm.org/D71378
Files:
clang/lib/AST/ASTImporter.cpp
lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py
lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp
lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
Index: lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
+++ lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
@@ -1,4 +1,4 @@
from lldbsuite.test import lldbinline
from lldbsuite.test import decorators
-lldbinline.MakeInlineTest(__file__, globals(), [decorators.skipIf(bugnumber="rdar://53756116")])
+lldbinline.MakeInlineTest(__file__, globals(), [])
Index: lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp
@@ -0,0 +1,39 @@
+// This is a reproducer for a crash in codegen. It happens when we have a
+// RecordDecl used in an expression and one of the FieldDecl are not complete.
+// This case happens when:
+// - A RecordDecl (E) has a FieldDecl which is a reference member variable
+// - The underlying type of the FieldDec is a TypedefDecl
+// - The typedef refers to a ClassTemplateSpecialization (DWrapper)
+// - The typedef is not present in the DeclContext of B
+// - The typedef shows up as a return value of a member function of E (f())
+template <typename T> struct DWrapper {};
+
+struct D {};
+
+namespace NS {
+typedef DWrapper<D> DW;
+}
+
+struct B {
+ NS::DW spd;
+ int a = 0;
+};
+
+struct E {
+ E(B &b) : b_ref(b) {}
+ NS::DW f() { return {}; };
+ void g() {
+ return; //%self.expect("p b_ref", substrs=['(B) $0 =', '(spd = NS::DW', 'a = 0)'])
+ }
+
+ B &b_ref;
+};
+
+int main() {
+ B b;
+ E e(b);
+
+ e.g();
+
+ return 0;
+}
Index: lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py
@@ -0,0 +1,4 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(__file__, globals(), [])
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -1734,7 +1734,34 @@
Error ChildErrors = Error::success();
for (auto *From : FromDC->decls()) {
ExpectedDecl ImportedOrErr = import(From);
- if (!ImportedOrErr) {
+
+ // If we are in the process of ImportDefinition(...) for a RecordDecl we
+ // want to make sure that we are also completing each FieldDecl. There
+ // are currently cases where this does not happen and this is correctness
+ // fix since operations such as code generation will expect this to be so.
+ if (ImportedOrErr) {
+ FieldDecl *FieldFrom = dyn_cast_or_null<FieldDecl>(From);
+ Decl *ImportedDecl = (Decl*)*ImportedOrErr;
+ FieldDecl *FieldTo = dyn_cast_or_null<FieldDecl>(ImportedDecl);
+ if (FieldFrom && FieldTo) {
+ const RecordType *RecordFrom = FieldFrom->getType()->getAs<RecordType>();
+ const RecordType *RecordTo = FieldTo->getType()->getAs<RecordType>();
+ if (RecordFrom && RecordTo) {
+ RecordDecl *FromRecordDecl = RecordFrom->getDecl();
+ RecordDecl *ToRecordDecl = RecordTo->getDecl();
+
+ if (FromRecordDecl->isCompleteDefinition() &&
+ !ToRecordDecl->isCompleteDefinition()) {
+ Error Err = ImportDefinition(FromRecordDecl, ToRecordDecl);
+
+ if (Err && AccumulateChildErrors)
+ ChildErrors = joinErrors(std::move(ChildErrors), std::move(Err));
+ else
+ consumeError(std::move(Err));
+ }
+ }
+ }
+ } else {
if (AccumulateChildErrors)
ChildErrors =
joinErrors(std::move(ChildErrors), ImportedOrErr.takeError());
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits