22 #include "llvm/ADT/ImmutableMap.h"
24 using namespace clang;
30 enum Kind { Opened, Closed, OpenFailed, Escaped } K;
33 StreamState(
Kind k,
const Stmt *s) : K(k),
S(s) {}
35 bool isOpened()
const {
return K == Opened; }
36 bool isClosed()
const {
return K == Closed; }
41 return K == X.K &&
S == X.S;
44 static StreamState getOpened(
const Stmt *s) {
return StreamState(Opened, s); }
45 static StreamState getClosed(
const Stmt *s) {
return StreamState(Closed, s); }
46 static StreamState getOpenFailed(
const Stmt *s) {
47 return StreamState(OpenFailed, s);
49 static StreamState getEscaped(
const Stmt *s) {
50 return StreamState(Escaped, s);
53 void Profile(llvm::FoldingSetNodeID &
ID)
const {
59 class StreamChecker :
public Checker<eval::Call,
60 check::DeadSymbols > {
61 mutable IdentifierInfo *II_fopen, *II_tmpfile, *II_fclose, *II_fread,
63 *II_fseek, *II_ftell, *II_rewind, *II_fgetpos, *II_fsetpos,
64 *II_clearerr, *II_feof, *II_ferror, *II_fileno;
65 mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence,
66 BT_doubleclose, BT_ResourceLeak;
70 : II_fopen(nullptr), II_tmpfile(nullptr), II_fclose(nullptr),
71 II_fread(nullptr), II_fwrite(nullptr), II_fseek(nullptr),
72 II_ftell(nullptr), II_rewind(nullptr), II_fgetpos(nullptr),
73 II_fsetpos(nullptr), II_clearerr(nullptr), II_feof(nullptr),
74 II_ferror(nullptr), II_fileno(nullptr) {}
110 if (!FD || FD->getKind() != Decl::Function)
135 II_clearerr = &Ctx.
Idents.
get(
"clearerr");
217 .castAs<DefinedSVal>();
224 std::tie(stateNotNull, stateNull) = CM.
assumeDual(state, RetVal);
229 stateNotNull->set<StreamMap>(Sym,StreamState::getOpened(CE));
231 stateNull->set<StreamMap>(Sym, StreamState::getOpenFailed(CE));
260 if (!(state = CheckNullStream(state->getSVal(CE->
getArg(0),
270 int64_t x = CI->getValue().getSExtValue();
271 if (x >= 0 && x <= 2)
275 if (!BT_illegalwhence)
276 BT_illegalwhence.reset(
277 new BuiltinBug(
this,
"Illegal whence argument",
278 "The whence argument to fseek() should be "
279 "SEEK_SET, SEEK_END, or SEEK_CUR."));
281 *BT_illegalwhence, BT_illegalwhence->getDescription(), N));
349 std::tie(stateNotNull, stateNull) = CM.
assumeDual(state, *DV);
351 if (!stateNotNull && stateNull) {
354 BT_nullfp.reset(
new BuiltinBug(
this,
"NULL stream pointer",
355 "Stream pointer might be NULL."));
357 *BT_nullfp, BT_nullfp->getDescription(), N));
372 const StreamState *SS = state->get<StreamMap>(Sym);
380 if (SS->isClosed()) {
385 this,
"Double fclose",
"Try to close a file Descriptor already"
386 " closed. Cause undefined behaviour."));
388 *BT_doubleclose, BT_doubleclose->getDescription(), N));
394 return state->set<StreamMap>(Sym, StreamState::getClosed(CE));
397 void StreamChecker::checkDeadSymbols(
SymbolReaper &SymReaper,
404 const StreamState *SS = state->get<StreamMap>(Sym);
408 if (SS->isOpened()) {
411 if (!BT_ResourceLeak)
413 this,
"Resource Leak",
414 "Opened File never closed. Potential Resource leak."));
416 *BT_ResourceLeak, BT_ResourceLeak->getDescription(), N));
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
bool operator==(CanQual< T > x, CanQual< U > y)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
Value representing integer constant.
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
unsigned blockCount() const
Returns the number of times the current block has been visited along the analyzed path...
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
dead_iterator dead_begin() const
detail::InMemoryDirectory::const_iterator I
const LocationContext * getLocationContext() const
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false...
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
const ProgramStateRef & getState() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
SymbolSetTy::const_iterator dead_iterator
ExplodedNode * generateNonFatalErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
dead_iterator dead_end() const
A class responsible for cleaning up unused symbols.
detail::InMemoryDirectory::const_iterator E
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
SValBuilder & getSValBuilder()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
const LocationContext * getLocationContext() const