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) {
68 for (
const Stmt *Child : S->children())
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> {
181 Finder.Visit(D->getBody());
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());
FunctionDecl - An instance of this class is created to represent 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.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
bool isVoidPointerType() const
ParenExpr - This represents a parethesized expression, e.g.
std::string getAsString() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
A container of type source information.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
UnaryExprOrTypeTrait getKind() const
const char *const UnixAPI
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.
ASTContext & getContext()
A builtin binary operation expression such as "x + y" or "x <= y".
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to...
detail::InMemoryDirectory::const_iterator I
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
Defines the clang::TypeLoc interface and its subclasses.
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.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
ASTMatchFinder *const Finder
CHECKER * registerChecker()
Used to register checkers.
ConstExprIterator const_arg_iterator
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
const TemplateArgument * iterator
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
detail::InMemoryDirectory::const_iterator E
ExplicitCastExpr - An explicit cast written in the source code.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
const T * getAs() const
Member-template getAs<specific type>'.
QualType getCanonicalType() const
SourceManager & getSourceManager()
const Expr * getSubExpr() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool isPointerType() const