23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
31 class VLASizeChecker :
public Checker< check::PreStmt<DeclStmt> > {
32 mutable std::unique_ptr<BugType> BT;
33 enum VLASize_Kind { VLA_Garbage, VLA_Zero, VLA_Tainted, VLA_Negative };
35 void reportBug(VLASize_Kind
Kind,
44 void VLASizeChecker::reportBug(VLASize_Kind
Kind,
55 this,
"Dangerous variable-length array (VLA) declaration"));
58 llvm::raw_svector_ostream os(buf);
59 os <<
"Declared variable-length array (VLA) ";
62 os <<
"uses a garbage value as its size";
65 os <<
"has zero size";
68 os <<
"has tainted size";
71 os <<
"has negative size";
75 auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
76 report->addRange(SizeE->getSourceRange());
100 reportBug(VLA_Garbage, SE, state, C);
110 if (state->isTainted(sizeV)) {
111 reportBug(VLA_Tainted, SE,
nullptr, C);
119 std::tie(stateNotZero, stateZero) = state->assume(sizeD);
121 if (stateZero && !stateNotZero) {
122 reportBug(VLA_Zero, SE, stateZero, C);
127 state = stateNotZero;
139 SVal LessThanZeroVal = svalBuilder.
evalBinOp(state, BO_LT, sizeD, Zero, Ty);
145 std::tie(StateNeg, StatePos) = CM.
assumeDual(state, *LessThanZeroDVal);
146 if (StateNeg && !StatePos) {
147 reportBug(VLA_Negative, SE, state, C);
164 state, BO_Mul, ArrayLength, EleSizeVal.
castAs<
NonLoc>(), SizeTy);
169 state->getRegion(VD, LC)->getExtent(svalBuilder);
172 svalBuilder.
evalEQ(state, Extent, ArraySize);
173 state = state->assume(sizeIsKnown,
true);
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
A (possibly-)qualified type.
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
SVal evalCast(SVal val, QualType castTy, QualType originalType)
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Expr * getSizeExpr() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false...
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
Expr - This represents one expression.
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...
SVal evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op, SVal lhs, SVal rhs, QualType type)
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl. ...
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy)=0
Create a new value which represents a binary expression with two non- location operands.
const Decl * getSingleDecl() const
ASTContext & getASTContext()
const VariableArrayType * getAsVariableArrayType(QualType T) const
DefinedOrUnknownSVal evalEQ(ProgramStateRef state, DefinedOrUnknownSVal lhs, DefinedOrUnknownSVal rhs)
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
Attempts to add visitors to trace a null or undefined value back to its point of origin, whether it is a symbol constrained to null or an explicit assignment.
SValBuilder & getSValBuilder()
QualType getElementType() const
Represents a C array with a specified size that is not an integer-constant-expression.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
const LocationContext * getLocationContext() const