diff options
5 files changed, 28 insertions, 62 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index ec8854ad80..eba9cc4c65 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -515,6 +515,8 @@ private: /// Traits for storing the call processing policy inside GDM. /// The GDM stores the corresponding CallExpr pointer. +// FIXME: This does not use the nice trait macros because it must be accessible +// from multiple translation units. struct ReplayWithoutInlining{}; template <> struct ProgramStateTrait<ReplayWithoutInlining> : diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h index 53205d3b72..c274cea841 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h @@ -22,6 +22,8 @@ namespace ento { /// The GDM component containing the tainted root symbols. We lazily infer the /// taint of the dependent symbols. Currently, this is a map from a symbol to /// tag kind. TODO: Should support multiple tag kinds. +// FIXME: This does not use the nice trait macros because it must be accessible +// from multiple translation units. struct TaintMap {}; typedef llvm::ImmutableMap<SymbolRef, TaintTagType> TaintMapImpl; template<> struct ProgramStateTrait<TaintMap> diff --git a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp index 012bca0a03..7a66ec3a93 100644 --- a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -163,23 +163,9 @@ public: }; } -namespace { struct NSErrorOut {}; } -namespace { struct CFErrorOut {}; } - typedef llvm::ImmutableMap<SymbolRef, unsigned> ErrorOutFlag; - -namespace clang { -namespace ento { - template <> - struct ProgramStateTrait<NSErrorOut> : public ProgramStatePartialTrait<ErrorOutFlag> { - static void *GDMIndex() { static int index = 0; return &index; } - }; - template <> - struct ProgramStateTrait<CFErrorOut> : public ProgramStatePartialTrait<ErrorOutFlag> { - static void *GDMIndex() { static int index = 0; return &index; } - }; -} -} +REGISTER_TRAIT_WITH_PROGRAMSTATE(NSErrorOut, ErrorOutFlag) +REGISTER_TRAIT_WITH_PROGRAMSTATE(CFErrorOut, ErrorOutFlag) template <typename T> static bool hasFlag(SVal val, ProgramStateRef state) { diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index 485959ad3f..f83acd9f6f 100644 --- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -99,31 +99,14 @@ enum SelfFlagEnum { }; } -typedef llvm::ImmutableMap<SymbolRef, unsigned> SelfFlag; -namespace { struct CalledInit {}; } -namespace { struct PreCallSelfFlags {}; } - -namespace clang { -namespace ento { - template<> - struct ProgramStateTrait<SelfFlag> : public ProgramStatePartialTrait<SelfFlag> { - static void *GDMIndex() { static int index = 0; return &index; } - }; - template <> - struct ProgramStateTrait<CalledInit> : public ProgramStatePartialTrait<bool> { - static void *GDMIndex() { static int index = 0; return &index; } - }; - - /// \brief A call receiving a reference to 'self' invalidates the object that - /// 'self' contains. This keeps the "self flags" assigned to the 'self' - /// object before the call so we can assign them to the new object that 'self' - /// points to after the call. - template <> - struct ProgramStateTrait<PreCallSelfFlags> : public ProgramStatePartialTrait<unsigned> { - static void *GDMIndex() { static int index = 0; return &index; } - }; -} -} +REGISTER_MAP_WITH_PROGRAMSTATE(SelfFlag, SymbolRef, unsigned) +REGISTER_TRAIT_WITH_PROGRAMSTATE(CalledInit, bool) + +/// \brief A call receiving a reference to 'self' invalidates the object that +/// 'self' contains. This keeps the "self flags" assigned to the 'self' +/// object before the call so we can assign them to the new object that 'self' +/// points to after the call. +REGISTER_TRAIT_WITH_PROGRAMSTATE(PreCallSelfFlags, unsigned) static SelfFlagEnum getSelfFlags(SVal val, ProgramStateRef state) { if (SymbolRef sym = val.getAsSymbol()) @@ -351,7 +334,7 @@ void ObjCSelfInitChecker::checkBind(SVal loc, SVal val, const Stmt *S, void ObjCSelfInitChecker::printState(raw_ostream &Out, ProgramStateRef State, const char *NL, const char *Sep) const { - SelfFlag FlagMap = State->get<SelfFlag>(); + SelfFlagTy FlagMap = State->get<SelfFlag>(); bool DidCallInit = State->get<CalledInit>(); SelfFlagEnum PreCallFlags = (SelfFlagEnum)State->get<PreCallSelfFlags>(); @@ -375,7 +358,8 @@ void ObjCSelfInitChecker::printState(raw_ostream &Out, ProgramStateRef State, } Out << NL; - for (SelfFlag::iterator I = FlagMap.begin(), E = FlagMap.end(); I != E; ++I) { + for (SelfFlagTy::iterator I = FlagMap.begin(), E = FlagMap.end(); + I != E; ++I) { Out << I->first << " : "; if (I->second == SelfFlag_None) diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index d021770b4d..c06ba7c304 100644 --- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -104,15 +104,8 @@ private: } // end anonymous namespace -namespace clang { -namespace ento { - template <> - struct ProgramStateTrait<StreamState> - : public ProgramStatePartialTrait<llvm::ImmutableMap<SymbolRef, StreamState> > { - static void *GDMIndex() { static int x; return &x; } - }; -} -} +REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState) + bool StreamChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { const FunctionDecl *FD = C.getCalleeDecl(CE); @@ -235,9 +228,9 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const { if (SymbolRef Sym = RetVal.getAsSymbol()) { // if RetVal is not NULL, set the symbol's state to Opened. stateNotNull = - stateNotNull->set<StreamState>(Sym,StreamState::getOpened(CE)); + stateNotNull->set<StreamMap>(Sym,StreamState::getOpened(CE)); stateNull = - stateNull->set<StreamState>(Sym, StreamState::getOpenFailed(CE)); + stateNull->set<StreamMap>(Sym, StreamState::getOpenFailed(CE)); C.addTransition(stateNotNull); C.addTransition(stateNull); @@ -378,7 +371,7 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE, if (!Sym) return state; - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); // If the file stream is not tracked, return. if (!SS) @@ -401,7 +394,7 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE, } // Close the File Descriptor. - return state->set<StreamState>(Sym, StreamState::getClosed(CE)); + return state->set<StreamMap>(Sym, StreamState::getClosed(CE)); } void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, @@ -411,7 +404,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, E = SymReaper.dead_end(); I != E; ++I) { SymbolRef Sym = *I; ProgramStateRef state = C.getState(); - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); // TODO: Shouldn't we have a continue here? if (!SS) return; @@ -432,10 +425,9 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, void StreamChecker::checkEndPath(CheckerContext &Ctx) const { ProgramStateRef state = Ctx.getState(); - typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap; - SymMap M = state->get<StreamState>(); + StreamMapTy M = state->get<StreamMap>(); - for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) { + for (StreamMapTy::iterator I = M.begin(), E = M.end(); I != E; ++I) { StreamState SS = I->second; if (SS.isOpened()) { ExplodedNode *N = Ctx.addTransition(state); @@ -462,12 +454,12 @@ void StreamChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { if (!Sym) return; - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); if(!SS) return; if (SS->isOpened()) - state = state->set<StreamState>(Sym, StreamState::getEscaped(S)); + state = state->set<StreamMap>(Sym, StreamState::getEscaped(S)); C.addTransition(state); } |