Author: shafik
Date: 2019-12-19T11:16:54-08:00
New Revision: 6a7df3a3f940473088b1db1ccadafe52bb274b62

URL: 
https://github.com/llvm/llvm-project/commit/6a7df3a3f940473088b1db1ccadafe52bb274b62
DIFF: 
https://github.com/llvm/llvm-project/commit/6a7df3a3f940473088b1db1ccadafe52bb274b62.diff

LOG: [ASTImporter][LLDB] Modifying ImportDeclContext(...) to ensure that we 
complete each FieldDecl of a RecordDecl when we are importing the definiton

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.

Differential Revision: https://reviews.llvm.org/D71378

Added: 
    
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

Modified: 
    clang/lib/AST/ASTImporter.cpp
    
lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index b75a689ec275..f495c48803d1 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1734,7 +1734,34 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, 
bool ForceImport) {
   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());

diff  --git 
a/lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py
 
b/lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/TestCodegenCrashTypedefDeclNotInDeclContext.py
new file mode 100644
index 000000000000..f08c0dcbda98
--- /dev/null
+++ 
b/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(), [])

diff  --git 
a/lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp
 
b/lldb/packages/Python/lldbsuite/test/commands/expression/codegen-crash-typedefdecl-not-in_declcontext/main.cpp
new file mode 100644
index 000000000000..e4f6600eab2c
--- /dev/null
+++ 
b/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;
+}

diff  --git 
a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
 
b/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
index 68bd864c0088..f08c0dcbda98 100644
--- 
a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-incomplete-record/TestCompletionCrashIncompleteRecord.py
+++ 
b/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(), [])


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to