martong created this revision.
martong added reviewers: xazax.hun, balazske, a_sidorin.
Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp, rnkovacs.

Adding some more CTU list tests. E.g. to check if a construct is unsupported.
We also slightly modify the handling of the return value of the `Import`
function from ASTImporter.


Repository:
  rC Clang

https://reviews.llvm.org/D55131

Files:
  lib/CrossTU/CrossTranslationUnit.cpp
  test/Analysis/Inputs/ctu-other.c
  test/Analysis/Inputs/externalFnMap2.txt
  test/Analysis/ctu-main.c

Index: test/Analysis/ctu-main.c
===================================================================
--- /dev/null
+++ test/Analysis/ctu-main.c
@@ -0,0 +1,60 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir2
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-pch -o %t/ctudir2/ctu-other.c.ast %S/Inputs/ctu-other.c
+// RUN: cp %S/Inputs/externalFnMap2.txt %t/ctudir2/externalFnMap.txt
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze -analyzer-checker=core,debug.ExprInspection  -analyzer-config experimental-enable-naive-ctu-analysis=true -analyzer-config ctu-dir=%t/ctudir2 -verify %s
+
+void clang_analyzer_eval(int);
+
+typedef struct {
+  int a;
+  int b;
+} foobar;
+
+static int s1 = 21;
+
+int f(int);
+int enumcheck(void);
+int static_check(void);
+
+enum A { x,
+         y,
+         z };
+
+extern foobar fb;
+
+int getkey();
+
+int main() {
+  clang_analyzer_eval(f(5) == 1);             // expected-warning{{TRUE}}
+  clang_analyzer_eval(x == 0);                // expected-warning{{TRUE}}
+  clang_analyzer_eval(enumcheck() == 42);     // expected-warning{{TRUE}}
+
+  return getkey();
+}
+
+// Test reporting error in a macro.
+struct S;
+int g(struct S *);
+void test_macro(void) {
+  g(0); // expected-warning@Inputs/ctu-other.c:31 {{Access to field 'a' results in a dereference of a null pointer (loaded from variable 'ctx')}}
+}
+
+// The external function prototype is incomplete.
+// warning:implicit functions are prohibited by c99
+void test_implicit(){
+    int res=ident_implicit(6);// external implicit functions are not inlined
+    clang_analyzer_eval(res == 6); // expected-warning{{TRUE}}
+}
+
+
+// Tests the import of functions that have a struct parameter
+// defined in its prototype.
+struct data_t{int a;int b;};
+int struct_in_proto(struct data_t *d);
+void test_struct_def_in_argument(){
+  struct data_t d;
+  d.a=1;
+  d.b=0;
+  clang_analyzer_eval(struct_in_proto(&d)==0);// expected-warning{{UNKNOWN}}
+}
Index: test/Analysis/Inputs/externalFnMap2.txt
===================================================================
--- /dev/null
+++ test/Analysis/Inputs/externalFnMap2.txt
@@ -0,0 +1,6 @@
+c:@F@getkey ctu-other.c.ast
+c:@F@g ctu-other.c.ast
+c:@F@f ctu-other.c.ast
+c:@F@enumcheck ctu-other.c.ast
+c:@F@ident_implicit ctu-other.c.ast
+c:@F@struct_in_proto ctu-other.c.ast
Index: test/Analysis/Inputs/ctu-other.c
===================================================================
--- /dev/null
+++ test/Analysis/Inputs/ctu-other.c
@@ -0,0 +1,51 @@
+enum B {x = 42,l,s};
+
+typedef struct {
+  int a;
+  int b;
+} foobar;
+
+int enumcheck(void) {
+  return x;
+}
+
+foobar fb;
+
+int f(int i) {
+  if (fb.a) {
+    fb.b = i;
+  }
+  return 1;
+}
+
+//TEST reporting an
+//error in macro
+//definition
+#define MYMACRO(ctx) \
+    ctx->a;
+struct S{
+  int a;
+};
+
+int g(struct S *ctx){
+  MYMACRO(ctx);
+  return 0;
+}
+
+// TEST asm import not failing
+int getkey() {
+  int res;
+  asm ( "mov $42, %0"
+      : "=r" (res));
+  return res;
+}
+
+//Implicit function
+int ident_implicit(int in){
+    return in;
+}
+
+//ASTImporter doesn't support this
+int struct_in_proto(struct data_t{int a;int b;} *d){
+  return 0;
+}
Index: lib/CrossTU/CrossTranslationUnit.cpp
===================================================================
--- lib/CrossTU/CrossTranslationUnit.cpp
+++ lib/CrossTU/CrossTranslationUnit.cpp
@@ -247,7 +247,10 @@
 CrossTranslationUnitContext::importDefinition(const FunctionDecl *FD) {
   ASTImporter &Importer = getOrCreateASTImporter(FD->getASTContext());
   auto *ToDecl =
-      cast<FunctionDecl>(Importer.Import(const_cast<FunctionDecl *>(FD)));
+      cast_or_null<FunctionDecl>(Importer.Import(const_cast<FunctionDecl *>(FD)));
+  if (!ToDecl) {
+    return llvm::make_error<IndexError>(index_error_code::failed_import);
+  }
   assert(ToDecl->hasBody());
   assert(FD->hasBody() && "Functions already imported should have body.");
   return ToDecl;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to