Go to the documentation of this file.
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
44 if (!II || !II->
getName().equals(NS))
51 T = QT->getNamedType();
62 return TD->
getName() ==
"string";
92 return TD->
getName() ==
"vector";
106 return TD->
getName() ==
"SmallVector";
115 class StringRefCheckerVisitor :
public StmtVisitor<StringRefCheckerVisitor> {
116 const Decl *DeclWithIssue;
118 const CheckerBase *Checker;
121 StringRefCheckerVisitor(
const Decl *declWithIssue, BugReporter &br,
122 const CheckerBase *checker)
123 : DeclWithIssue(declWithIssue), BR(br), Checker(checker) {}
124 void VisitChildren(
Stmt *S) {
125 for (
Stmt *Child : S->children())
129 void VisitStmt(
Stmt *S) { VisitChildren(S); }
132 void VisitVarDecl(
VarDecl *VD);
137 const CheckerBase *Checker) {
138 StringRefCheckerVisitor walker(D, BR, Checker);
142 void StringRefCheckerVisitor::VisitDeclStmt(
DeclStmt *S) {
145 for (
auto *I : S->decls())
146 if (
VarDecl *VD = dyn_cast<VarDecl>(I))
150 void StringRefCheckerVisitor::VisitVarDecl(
VarDecl *VD) {
179 const char *desc =
"StringRef should not be bound to temporary "
180 "std::string that it outlives";
181 PathDiagnosticLocation VDLoc =
183 BR.EmitBasicReport(DeclWithIssue, Checker, desc,
"LLVM Conventions", desc,
184 VDLoc, Init->getSourceRange());
201 for (
const auto &BS : R->
bases()) {
204 CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
214 class ASTFieldVisitor {
218 const CheckerBase *Checker;
222 const CheckerBase *checker)
223 : Root(root), BR(br), Checker(checker) {}
231 const CheckerBase *Checker) {
235 for (
auto *I : R->
fields()) {
236 ASTFieldVisitor walker(R, BR, Checker);
241 void ASTFieldVisitor::Visit(
FieldDecl *D) {
242 FieldChain.push_back(D);
251 for (
auto *I : RD->
fields())
255 FieldChain.pop_back();
258 void ASTFieldVisitor::ReportError(
QualType T) {
260 llvm::raw_svector_ostream os(buf);
262 os <<
"AST class '" << Root->getName() <<
"' has a field '"
263 << FieldChain.front()->getName() <<
"' that allocates heap memory";
264 if (FieldChain.size() > 1) {
265 os <<
" via the following chain: ";
268 E=FieldChain.end(); I!=E; ++I) {
273 os << (*I)->getName();
276 os <<
" (type " << FieldChain.back()->getType().getAsString() <<
")";
286 FieldChain.front(), BR.getSourceManager());
287 BR.EmitBasicReport(Root, Checker,
"AST node allocates heap memory",
288 "LLVM Conventions", os.str(), L);
296 class LLVMConventionsChecker :
public Checker<
297 check::ASTDecl<CXXRecordDecl>,
298 check::ASTCodeBody > {
300 void checkASTDecl(
const CXXRecordDecl *R, AnalysisManager& mgr,
301 BugReporter &BR)
const {
306 void checkASTCodeBody(
const Decl *D, AnalysisManager& mgr,
307 BugReporter &BR)
const {
313 void ento::registerLLVMConventionsChecker(CheckerManager &mgr) {
314 mgr.registerChecker<LLVMConventionsChecker>();
317 bool ento::shouldRegisterLLVMConventionsChecker(
const CheckerManager &mgr) {
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
static bool IsClangDecl(const RecordDecl *RD)
static bool IsStdString(QualType T)
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
A (possibly-)qualified type.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Represents a member of a struct/union/class.
static bool IsPartOfAST(const CXXRecordDecl *R)
Represents a type template specialization; the template must be a class template, a type alias templa...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
static bool IsClangType(const RecordDecl *RD)
static bool AllocatesMemory(QualType T)
static bool IsStdVector(QualType T)
llvm::StringRef getAsString(SyncScope S)
static bool IsClangStmt(const RecordDecl *RD)
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static bool IsClangAttr(const RecordDecl *RD)
Represents binding an expression to a temporary.
bool isInStdNamespace() const
const T * getAs() const
Member-template getAs<specific type>'.
static bool IsLLVMStringRef(QualType T)
static bool InNamespace(const Decl *D, StringRef NS)
Check whether the declaration is semantically inside the top-level namespace named by ns.
static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR, const CheckerBase *Checker)
Represents a variable declaration or definition.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR, const CheckerBase *Checker)
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
const Expr * getSubExpr() const
Represents a C++ struct/union/class.
TypedefNameDecl * getDecl() const
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a C++ template name within the type system.
field_range fields() const
The base class of all kinds of template declarations (e.g., class, function, etc.).
Decl - This represents one declaration (or definition), e.g.
const Expr * getInit() const
One of these records is kept for each identifier that is lexed.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
Stmt - This represents one statement.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Base class for declarations which introduce a typedef-name.
static bool IsSmallVector(QualType T)
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Expr * getArg(unsigned Arg)
Return the specified argument.
This represents one expression.
Represent a C++ namespace.
Represents a struct/union/class.
Represents a call to a C++ constructor.
DeclContext * getDeclContext()
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.