From: Yury Gribov Date: Mon, 11 Jan 2016 09:38:48 +0000 (+0000) Subject: AnalysisConsumer: use canonical decl for both lookup and store of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0bfbb2d27215fc5529b626902a4c538dca916e88;p=clang AnalysisConsumer: use canonical decl for both lookup and store of visited decls. Due to redeclarations, the function may have different declarations used in CallExpr and in the definition. However, we need to use a unique declaration for both store and lookup in VisitedCallees. This patch fixes issues with analysis in topological order. A simple test is included. Patch by Alex Sidorin! Differential Revision: http://reviews.llvm.org/D15410 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257318 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index bf85c4ca0c..d1446855e0 100644 --- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -496,10 +496,11 @@ void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) { (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees)); // Add the visited callees to the global visited set. - for (SetOfConstDecls::iterator I = VisitedCallees.begin(), - E = VisitedCallees.end(); I != E; ++I) { - Visited.insert(*I); - } + for (const Decl *Callee : VisitedCallees) + // Decls from CallGraph are already canonical. But Decls coming from + // CallExprs may be not. We should canonicalize them manually. + Visited.insert(isa(Callee) ? Callee + : Callee->getCanonicalDecl()); VisitedAsTopLevel.insert(D); } } diff --git a/test/Analysis/inlining/analysis-order.c b/test/Analysis/inlining/analysis-order.c new file mode 100644 index 0000000000..5149818c74 --- /dev/null +++ b/test/Analysis/inlining/analysis-order.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin.NoReturnFunctions -analyzer-display-progress %s 2>&1 | FileCheck %s + +// Do not analyze test1() again because it was inlined +void test1(); + +void test2() { + test1(); +} + +void test1() { +} + +// CHECK: analysis-order.c test2 +// CHECK-NEXT: analysis-order.c test1 +// CHECK-NEXT: analysis-order.c test2