diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp --- a/clang/lib/AST/ASTImporterLookupTable.cpp +++ b/clang/lib/AST/ASTImporterLookupTable.cpp @@ -22,6 +22,20 @@ struct Builder : RecursiveASTVisitor { ASTImporterLookupTable < Builder(ASTImporterLookupTable <) : LT(LT) {} + + bool VisitTypedefNameDecl(TypedefNameDecl *D) { + QualType Ty = D->getUnderlyingType(); + Ty = Ty.getCanonicalType(); + if (const auto *RTy = dyn_cast(Ty)) { + LT.add(RTy->getAsRecordDecl()); + // iterate over the field decls, adding them + for (auto *it : RTy->getAsRecordDecl()->fields()) { + LT.add(it); + } + } + return true; + } + bool VisitNamedDecl(NamedDecl *D) { LT.add(D); return true; diff --git a/clang/test/Analysis/Inputs/ctu-import.c b/clang/test/Analysis/Inputs/ctu-import.c new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-import.c @@ -0,0 +1,15 @@ + +// Use an internal, implicitly defined type, called by +// a function imported for CTU. This should not crash. +int foo(void); +int foobar(int skip) { + __NSConstantString str = {.flags = 1}; + + if (str.flags >= 0) + str.flags = 0; + return 4; +} + +int testStaticImplicit(void) { + return foobar(3); +} diff --git a/clang/test/Analysis/Inputs/ctu-import.c.externalDefMap.ast-dump.txt b/clang/test/Analysis/Inputs/ctu-import.c.externalDefMap.ast-dump.txt new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-import.c.externalDefMap.ast-dump.txt @@ -0,0 +1 @@ +c:@F@testStaticImplicit ctu-import.c.ast diff --git a/clang/test/Analysis/ctu-implicit.c b/clang/test/Analysis/ctu-implicit.c new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/ctu-implicit.c @@ -0,0 +1,20 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir2 +// RUN: %clang_cc1 \ +// RUN: -emit-pch -o %t/ctudir2/ctu-import.c.ast %S/Inputs/ctu-import.c +// RUN: cp %S/Inputs/ctu-import.c.externalDefMap.ast-dump.txt %t/ctudir2/externalDefMap.txt +// RUN: %clang_cc1 -analyze \ +// RUN: -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config display-ctu-progress=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir2 \ +// RUN: -verify %s + +void clang_analyzer_eval(int); + +int testStaticImplicit(void); +int func(void) { + int ret = testStaticImplicit(); + clang_analyzer_eval(ret == 4); // expected-warning{{TRUE}} + return testStaticImplicit(); +}