From f761acfb1a737d8a631a5e55b58cdb7c2215baad Mon Sep 17 00:00:00 2001 From: Vince Bridgers Date: Thu, 16 Jul 2020 17:46:48 -0500 Subject: [PATCH] [ASTImporter] Add Visitor for TypedefNameDecl's We found a case where Typedef Name Declarations were not being added correctly when importing builtin types. This exposed the need for a TypedefNameDecl visitor so these types can be added by RecordDecl and fields. This code is covered by the ASTImporterTest cases that use the implicit struct __NSConstantString_tag definitions. Thanks to @martong for the debugging assist! Depends on D83970. Reviewed By: martong Differential Revision: https://reviews.llvm.org/D83992 --- clang/lib/AST/ASTImporterLookupTable.cpp | 14 +++++++++++++ clang/test/Analysis/Inputs/ctu-import.c | 15 ++++++++++++++ .../ctu-import.c.externalDefMap.ast-dump.txt | 1 + clang/test/Analysis/ctu-implicit.c | 20 +++++++++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 clang/test/Analysis/Inputs/ctu-import.c create mode 100644 clang/test/Analysis/Inputs/ctu-import.c.externalDefMap.ast-dump.txt create mode 100644 clang/test/Analysis/ctu-implicit.c diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp index 4d6fff8f3419..e17d6082dcdc 100644 --- a/clang/lib/AST/ASTImporterLookupTable.cpp +++ b/clang/lib/AST/ASTImporterLookupTable.cpp @@ -22,6 +22,20 @@ namespace { 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 index 000000000000..6c99a3642797 --- /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 index 000000000000..83d3b4ca451e --- /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 index 000000000000..925044845e09 --- /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(); +}