20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/Support/raw_ostream.h" 23 using namespace clang;
46 if (!II || !II->
getName().equals(NS))
53 T = QT->getNamedType();
64 return TD->
getName() ==
"string";
94 return TD->
getName() ==
"vector";
108 return TD->
getName() ==
"SmallVector";
117 class StringRefCheckerVisitor :
public StmtVisitor<StringRefCheckerVisitor> {
118 const Decl *DeclWithIssue;
125 : DeclWithIssue(declWithIssue), BR(br), Checker(checker) {}
126 void VisitChildren(
Stmt *S) {
131 void VisitStmt(
Stmt *S) { VisitChildren(S); }
134 void VisitVarDecl(
VarDecl *VD);
140 StringRefCheckerVisitor walker(D, BR, Checker);
144 void StringRefCheckerVisitor::VisitDeclStmt(
DeclStmt *S) {
147 for (
auto *I : S->
decls())
148 if (
VarDecl *VD = dyn_cast<VarDecl>(I))
152 void StringRefCheckerVisitor::VisitVarDecl(
VarDecl *VD) {
181 const char *desc =
"StringRef should not be bound to temporary " 182 "std::string that it outlives";
185 BR.EmitBasicReport(DeclWithIssue,
Checker, desc,
"LLVM Conventions", desc,
203 for (
const auto &BS : R->
bases()) {
206 CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
216 class ASTFieldVisitor {
225 : Root(root), BR(br), Checker(checker) {}
237 for (
auto *I : R->
fields()) {
238 ASTFieldVisitor walker(R, BR, Checker);
243 void ASTFieldVisitor::Visit(
FieldDecl *D) {
244 FieldChain.push_back(D);
253 for (
auto *I : RD->
fields())
257 FieldChain.pop_back();
260 void ASTFieldVisitor::ReportError(
QualType T) {
262 llvm::raw_svector_ostream os(buf);
264 os <<
"AST class '" << Root->getName() <<
"' has a field '" 265 << FieldChain.front()->getName() <<
"' that allocates heap memory";
266 if (FieldChain.size() > 1) {
267 os <<
" via the following chain: ";
270 E=FieldChain.end(); I!=E; ++I) {
275 os << (*I)->getName();
278 os <<
" (type " << FieldChain.back()->getType().getAsString() <<
")";
288 FieldChain.front(), BR.getSourceManager());
289 BR.EmitBasicReport(Root,
Checker,
"AST node allocates heap memory",
290 "LLVM Conventions", os.str(), L);
298 class LLVMConventionsChecker :
public Checker<
299 check::ASTDecl<CXXRecordDecl>,
300 check::ASTCodeBody > {
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
A (possibly-)qualified type.
static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR, const CheckerBase *Checker)
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.
Decl - This represents one declaration (or definition), e.g.
Defines the C++ template declaration subclasses.
Represent a C++ namespace.
Represents a call to a C++ constructor.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
Represents a member of a struct/union/class.
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
Represents binding an expression to a temporary.
static bool IsPartOfAST(const CXXRecordDecl *R)
static bool IsStdString(QualType T)
Expr - This represents one expression.
llvm::StringRef getAsString(SyncScope S)
DeclContext * getDeclContext()
Represents a C++ template name within the type system.
static bool IsClangType(const RecordDecl *RD)
CHECKER * registerChecker(AT... Args)
Used to register checkers.
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.
static bool IsSmallVector(QualType T)
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static bool IsStdVector(QualType T)
static bool IsClangDecl(const RecordDecl *RD)
static bool IsClangStmt(const RecordDecl *RD)
StringRef getName() const
Return the actual identifier string.
Base class for declarations which introduce a typedef-name.
Dataflow Directional Tag Classes.
The base class of all kinds of template declarations (e.g., class, function, etc.).
const Expr * getInit() const
static bool InNamespace(const Decl *D, StringRef NS)
Check whether the declaration is semantically inside the top-level namespace named by ns...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
static bool IsLLVMStringRef(QualType T)
Expr * getArg(unsigned Arg)
Return the specified argument.
TypedefNameDecl * getDecl() const
Represents a C++ struct/union/class.
static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR, const CheckerBase *Checker)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
static bool AllocatesMemory(QualType T)
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a type template specialization; the template must be a class template, a type alias templa...
unsigned getNumArgs() const
bool isInStdNamespace() const
static bool IsClangAttr(const RecordDecl *RD)