Index: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -93,6 +93,12 @@ ProgramStateRef makeWithStore(const StoreRef &store) const; void setStore(const StoreRef &storeRef); + + // Create a new state in which the statement is marked as tainted or + // non-tainted, depending on the AddOp value. If it is true the operation + // carried out will be 'add', otherwise 'remove'. + ProgramStateRef doTaintOperation(const Stmt *S, const LocationContext *LCtx, + TaintTagType Kind, bool AddOp = true) const; public: /// This ctor is used when creating the first ProgramState object. @@ -330,6 +336,18 @@ ProgramStateRef addTaint(const MemRegion *R, TaintTagType Kind = TaintTagGeneric) const; + /// Create a new state in which the statement is marked as non-tainted. + ProgramStateRef removeTaint(const Stmt *S, const LocationContext *LCtx, + TaintTagType Kind = TaintTagGeneric) const; + + /// Create a new state in which the symbol is marked as non-tainted. + ProgramStateRef removeTaint(SymbolRef S, TaintTagType Kind = TaintTagGeneric) + const; + + /// Create a new state in which the region symbol is marked as non-tainted. + ProgramStateRef removeTaint(const MemRegion *R, TaintTagType Kind = + TaintTagGeneric) const; + /// Check if the statement is tainted in the current state. bool isTainted(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind = TaintTagGeneric) const; Index: lib/StaticAnalyzer/Core/ProgramState.cpp =================================================================== --- lib/StaticAnalyzer/Core/ProgramState.cpp +++ lib/StaticAnalyzer/Core/ProgramState.cpp @@ -648,23 +648,34 @@ return true; } -ProgramStateRef ProgramState::addTaint(const Stmt *S, - const LocationContext *LCtx, - TaintTagType Kind) const { +ProgramStateRef ProgramState::doTaintOperation(const Stmt *S, const LocationContext + *LCtx, TaintTagType Kind, bool + AddOp) const { if (const Expr *E = dyn_cast_or_null(S)) S = E->IgnoreParens(); SymbolRef Sym = getSVal(S, LCtx).getAsSymbol(); - if (Sym) + if (Sym && AddOp) return addTaint(Sym, Kind); + if (Sym && !AddOp) + return removeTaint(Sym, Kind); const MemRegion *R = getSVal(S, LCtx).getAsRegion(); - addTaint(R, Kind); + if (AddOp) + addTaint(R, Kind); + else + removeTaint(R, Kind); - // Cannot add taint, so just return the state. + // Cannot add/remove taint, so just return the state. return this; } +ProgramStateRef ProgramState::addTaint(const Stmt *S, + const LocationContext *LCtx, + TaintTagType Kind) const { + return doTaintOperation(S, LCtx, Kind, true); +} + ProgramStateRef ProgramState::addTaint(const MemRegion *R, TaintTagType Kind) const { if (const SymbolicRegion *SR = dyn_cast_or_null(R)) @@ -684,6 +695,30 @@ return NewState; } +ProgramStateRef ProgramState::removeTaint(const Stmt *S, const LocationContext + *LCtx, TaintTagType Kind) const { + return doTaintOperation(S, LCtx, Kind, false); +} + +ProgramStateRef ProgramState::removeTaint(const MemRegion *R, TaintTagType Kind) + const { + if (const SymbolicRegion *SR = dyn_cast_or_null(R)) + return removeTaint(SR->getSymbol(), Kind); + return this; +} + +ProgramStateRef ProgramState::removeTaint(SymbolRef Sym, TaintTagType Kind) + const { + // If this is a symbol cast, remove the cast before removing the taint. Taint + // is cast agnostic. + while (const SymbolCast *SC = dyn_cast(Sym)) + Sym = SC->getOperand(); + + ProgramStateRef NewState = remove(Sym); + assert(NewState); + return NewState; +} + bool ProgramState::isTainted(const Stmt *S, const LocationContext *LCtx, TaintTagType Kind) const { if (const Expr *E = dyn_cast_or_null(S))