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(Importer.Import(const_cast(FD))); + cast_or_null(Importer.Import(const_cast(FD))); + if (!ToDecl) { + return llvm::make_error(index_error_code::failed_import); + } assert(ToDecl->hasBody()); assert(FD->hasBody() && "Functions already imported should have body."); return ToDecl; 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: 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/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}} +}