From 2964aac03b250dadbc1ed14a4d7d170093452c2f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 27 Apr 2012 04:54:28 +0000 Subject: [PATCH] Use a deque instead of an ImmutableList in AnalysisConsumer to preserve the file order that functions are visited. Should fix the buildbots. llvm-svn: 155693 --- .../Core/PathSensitive/FunctionSummary.h | 4 ++-- .../Frontend/AnalysisConsumer.cpp | 22 +++++++------------ ...ceiver-undefined-larger-than-voidptr-ret.m | 8 +++---- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h index 3f7243293598..cf4a6929a3aa 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -14,15 +14,15 @@ #ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H #define LLVM_CLANG_GR_FUNCTIONSUMMARY_H +#include #include "clang/AST/Decl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/ImmutableList.h" namespace clang { namespace ento { -typedef llvm::ImmutableList SetOfDecls; +typedef std::deque SetOfDecls; typedef llvm::DenseSet SetOfConstDecls; class FunctionSummariesTy { diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index dd60b201f810..ae783230f689 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -102,8 +102,6 @@ public: /// The local declaration to all declarations ratio might be very small when /// working with a PCH file. SetOfDecls LocalTUDecls; - - SetOfDecls::Factory LocalTUDeclsFactory; // PD is owned by AnalysisManager. PathDiagnosticConsumer *PD; @@ -308,9 +306,7 @@ void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) { if (isa(*I)) continue; - // We use an ImmutableList to avoid issues with invalidating iterators - // to the list while we are traversing it. - LocalTUDecls = LocalTUDeclsFactory.add(*I, LocalTUDecls); + LocalTUDecls.push_back(*I); } } @@ -319,9 +315,6 @@ void AnalysisConsumer::HandleDeclsGallGraph() { // Build the Call Graph. CallGraph CG; // Add all the top level declarations to the graph. - // - // NOTE: We use an ImmutableList to avoid issues with invalidating iterators - // to the list while we are traversing it. for (SetOfDecls::iterator I = LocalTUDecls.begin(), E = LocalTUDecls.end(); I != E; ++I) CG.addToCallGraph(*I); @@ -410,12 +403,13 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { // Process all the top level declarations. // - // NOTE: We use an ImmutableList to avoid issues with invalidating iterators - // to the list while we are traversing it. - // - for (SetOfDecls::iterator I = LocalTUDecls.begin(), - E = LocalTUDecls.end(); I != E; ++I) { - TraverseDecl(*I); + // Note: TraverseDecl may modify LocalTUDecls, but only by appending more + // entries. Thus we don't use an iterator, but rely on LocalTUDecls + // random access. By doing so, we automatically compensate for iterators + // possibly being invalidated, although this is a bit slower. + const unsigned n = LocalTUDecls.size(); + for (unsigned i = 0 ; i < n ; ++i) { + TraverseDecl(LocalTUDecls[i]); } if (Mgr->shouldInlineCall()) diff --git a/clang/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/clang/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m index e4d5aaf82b2d..7cf2aee35fc0 100644 --- a/clang/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m +++ b/clang/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m @@ -80,11 +80,11 @@ int handleVoidInComma() { int marker(void) { // control reaches end of non-void function } -// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage -// CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage -// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage -// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage // CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage +// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage // CHECK-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage // CHECK-darwin9-NOT: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage