shafik created this revision.
shafik added reviewers: martong, teemperor.
Herald added a subscriber: rnkovacs.
This fix was motivated by a crashes in expression parsing during code
generation in which we had a `RecordDecl` that had incomplete `FieldDecl`.
During code generation when computing the layout for the `RecordDecl` we crash
because we have several incomplete `FieldDecl`.
This fixes the issue by assuring that during `ImportDefinition(...)` for a
`RecordDecl` we also import the definitions for each `FieldDecl`.
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,41 @@
+// 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
@@ -1683,6 +1683,33 @@
Error ChildErrors = Error::success();
for (auto *From : FromDC->decls()) {
ExpectedDecl ImportedOrErr = import(From);
+
+ // If we are in the process of ImportDefinition(...) for a RecordDecl we
+ // want to make sure that we are also completeing 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)
+ return Err;
+ }
+ }
+ }
+ }
+
if (!ImportedOrErr) {
if (AccumulateChildErrors)
ChildErrors =
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits