23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/Support/raw_ostream.h" 26 using namespace clang;
31 typedef std::pair<const TypeSourceInfo *, const CallExpr *> TypeCallPair;
32 typedef llvm::PointerUnion<const Stmt *, const VarDecl *> ExprParent;
34 class CastedAllocFinder
40 ExprParent CastedExprParent;
41 const Expr *CastedExpr;
45 CallRecord(ExprParent CastedExprParent,
const Expr *CastedExpr,
48 : CastedExprParent(CastedExprParent), CastedExpr(CastedExpr),
49 ExplicitCastType(ExplicitCastType), AllocCall(AllocCall) {}
52 typedef std::vector<CallRecord> CallVec;
56 II_malloc(&Ctx->Idents.get(
"malloc")),
57 II_calloc(&Ctx->Idents.get(
"calloc")),
58 II_realloc(&Ctx->Idents.get(
"realloc")) {}
60 void VisitChild(ExprParent
Parent,
const Stmt *S) {
61 TypeCallPair AllocCall = Visit(S);
62 if (AllocCall.second && AllocCall.second != S)
63 Calls.push_back(CallRecord(Parent, cast<Expr>(S), AllocCall.first,
67 void VisitChildren(
const Stmt *S) {
73 TypeCallPair VisitCastExpr(
const CastExpr *E) {
82 TypeCallPair VisitParenExpr(
const ParenExpr *E) {
86 TypeCallPair VisitStmt(
const Stmt *S) {
88 return TypeCallPair();
91 TypeCallPair VisitCallExpr(
const CallExpr *E) {
96 if (II == II_malloc || II == II_calloc || II == II_realloc)
99 return TypeCallPair();
102 TypeCallPair VisitDeclStmt(
const DeclStmt *S) {
103 for (
const auto *I : S->
decls())
104 if (
const VarDecl *VD = dyn_cast<VarDecl>(I))
105 if (
const Expr *Init = VD->getInit())
106 VisitChild(VD, Init);
107 return TypeCallPair();
113 std::vector<const UnaryExprOrTypeTraitExpr *> Sizeofs;
124 void VisitParenExpr(
const ParenExpr *E) {
132 Sizeofs.push_back(E);
166 QualType ElemType = AT->getElementType();
167 if (typesCompatible(C, PT, AT->getElementType()))
175 class MallocSizeofChecker :
public Checker<check::ASTCodeBody> {
182 for (CastedAllocFinder::CallVec::iterator i = Finder.Calls.begin(),
183 e = Finder.Calls.end(); i != e; ++i) {
184 QualType CastedType = i->CastedExpr->getType();
192 ae = i->AllocCall->arg_end(); ai != ae; ++ai) {
193 if (!(*ai)->getType()->isIntegralOrUnscopedEnumerationType())
196 SizeofFinder SFinder;
198 if (SFinder.Sizeofs.size() != 1)
201 QualType SizeofType = SFinder.Sizeofs[0]->getTypeOfArgument();
203 if (typesCompatible(BR.
getContext(), PointeeType, SizeofType))
208 if (compatibleWithArrayType(BR.
getContext(), PointeeType, SizeofType))
212 if (i->CastedExprParent.is<
const VarDecl *>()) {
214 i->CastedExprParent.get<
const VarDecl *>()->getTypeSourceInfo();
216 TSI = i->ExplicitCastType;
220 llvm::raw_svector_ostream OS(buf);
223 const FunctionDecl *Callee = i->AllocCall->getDirectCallee();
228 OS <<
" is converted to a pointer of type '" 229 << PointeeType.
getAsString() <<
"', which is incompatible with " 230 <<
"sizeof operand type '" << SizeofType.
getAsString() <<
"'";
232 Ranges.push_back(i->AllocCall->getCallee()->getSourceRange());
233 Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange());
Represents a function declaration or definition.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Stmt - This represents one statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Decl - This represents one declaration (or definition), e.g.
ParenExpr - This represents a parethesized expression, e.g.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to...
A container of type source information.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
const char *const UnixAPI
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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 ...
AnalysisDeclContext contains the context data for the function or method under analysis.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
ASTContext & getContext()
A builtin binary operation expression such as "x + y" or "x <= y".
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
Const iterator for iterating over Stmt * arrays that contain only Expr *.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
Expr - This represents one expression.
Defines the clang::TypeLoc interface and its subclasses.
const Expr * getSubExpr() const
CHECKER * registerChecker(AT... Args)
Used to register checkers.
bool isVoidPointerType() const
BugReporter is a utility class for generating PathDiagnostics for analysis.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
QualType getCanonicalType() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
UnaryExprOrTypeTrait getKind() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
ExplicitCastExpr - An explicit cast written in the source code.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
SourceManager & getSourceManager()
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool isPointerType() const
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)