summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-11-02 01:54:42 +0000
committerJordan Rose <jordan_rose@apple.com>2012-11-02 01:54:42 +0000
commitb9ed61f93d00501eaecb23cc34371be5ff0afd3c (patch)
tree37b8671bdd7286664dc3590c5ce55491a7931f1a /clang/lib
parent0c153cb277ce78d88c7457170d5260982c9d4e6a (diff)
downloadbcm5719-llvm-b9ed61f93d00501eaecb23cc34371be5ff0afd3c.tar.gz
bcm5719-llvm-b9ed61f93d00501eaecb23cc34371be5ff0afd3c.zip
[analyzer] Convert some of the harder cases over to ProgramStateTrait macros.
Add FIXMEs for the traits visible from multiple translation units. Currently the macros hide their key types in an anonymous namespace. llvm-svn: 167277
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp18
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp38
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp30
3 files changed, 24 insertions, 62 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
index 012bca0a038..7a66ec3a934 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 485959ad3f4..f83acd9f6ff 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/clang/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/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index d021770b4d2..c06ba7c304e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/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);
}
OpenPOWER on IntegriCloud