=?utf-8?q?Balázs_Kéri?= <balazs.k...@ericsson.com>,
=?utf-8?q?Balázs_Kéri?= <balazs.k...@ericsson.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/156...@github.com>


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balázs Kéri (balazske)

<details>
<summary>Changes</summary>

When a type is imported with `ASTImporter`, the "original declaration"
of the type is imported. In some cases this is not the definition
(of the class). Before the fix the definition was only imported if
there was an other reference to it in the AST to import. This is not
always the case (like in the added test case), if not the definition
was missing in the "To" AST which can cause the assertion later.

---
Full diff: https://github.com/llvm/llvm-project/pull/156056.diff


2 Files Affected:

- (modified) clang/lib/AST/ASTImporter.cpp (+12-1) 
- (added) clang/test/Analysis/ctu-import-type-decl-definition.c (+43) 


``````````diff
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 6299efaf6bbfc..d2ea60896094f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -1740,10 +1740,21 @@ ExpectedType 
ASTNodeImporter::VisitDeducedTemplateSpecializationType(
 }
 
 ExpectedType ASTNodeImporter::VisitTagType(const TagType *T) {
-  Expected<TagDecl *> ToDeclOrErr = import(T->getOriginalDecl());
+  TagDecl *DeclForType = T->getOriginalDecl();
+  Expected<TagDecl *> ToDeclOrErr = import(DeclForType);
   if (!ToDeclOrErr)
     return ToDeclOrErr.takeError();
 
+  if (DeclForType->isUsed()) {
+    // If there is a definition of the 'OriginalDecl', it should be imported to
+    // have all information for the type in the "To" AST. (In some cases no
+    // other reference may exist to the definition decl and it would not be
+    // imported otherwise.)
+    Expected<TagDecl *> ToDefDeclOrErr = import(DeclForType->getDefinition());
+    if (!ToDefDeclOrErr)
+      return ToDefDeclOrErr.takeError();
+  }
+
   if (T->isCanonicalUnqualified())
     return Importer.getToContext().getCanonicalTagType(*ToDeclOrErr);
 
diff --git a/clang/test/Analysis/ctu-import-type-decl-definition.c 
b/clang/test/Analysis/ctu-import-type-decl-definition.c
new file mode 100644
index 0000000000000..6d95fd5686cb4
--- /dev/null
+++ b/clang/test/Analysis/ctu-import-type-decl-definition.c
@@ -0,0 +1,43 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -emit-pch -o %t/import.c.ast %t/import.c
+
+// RUN: %clang_extdef_map -- -x c %t/import.c >> %t/externalDefMap.txt
+// RUN: sed -i'' 's/$/.ast/' %t/externalDefMap.txt
+
+// RUN: %clang_cc1 -analyze \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config display-ctu-progress=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   -verify %t/main.c
+
+//--- main.c
+
+// expected-no-diagnostics
+
+typedef struct X_s X_t;
+unsigned long f_import(struct X_s *xPtr);
+
+static void freeWriteFileResources(struct X_s *xPtr) {
+  f_import(xPtr);
+}
+
+//--- import.c
+
+typedef struct Y_s Y_t;
+
+struct Y_s {
+};
+
+struct X_s {
+  Y_t y;
+};
+
+unsigned long f_import(struct X_s *xPtr) {
+  if (xPtr != 0) {
+  }
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/156056
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to