20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/Support/raw_ostream.h"
23 using namespace clang;
35 return StringRef(
QualType(RT, 0).getAsString()) ==
46 if (!II || !II->
getName().equals(NS))
48 return isa<TranslationUnitDecl>(ND->getDeclContext());
53 T = QT->getNamedType();
61 if (!TD->isInStdNamespace())
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) {
127 for (
Stmt *Child : S->children())
131 void VisitStmt(
Stmt *S) { VisitChildren(S); }
134 void VisitVarDecl(
VarDecl *VD);
140 StringRefCheckerVisitor walker(D, BR, Checker);
141 walker.Visit(D->getBody());
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,
186 VDLoc, Init->getSourceRange());
203 for (
const auto &BS : R->
bases()) {
206 CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
216 class ASTFieldVisitor {
225 : Root(root), BR(br),
Checker(checker) {}
238 ASTFieldVisitor walker(R, BR, Checker);
243 void ASTFieldVisitor::Visit(
FieldDecl *D) {
244 FieldChain.push_back(D);
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...
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR, const CheckerBase *Checker)
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
Defines the C++ template declaration subclasses.
const Expr * getInit() const
NamespaceDecl - Represent a C++ namespace.
Represents a call to a C++ constructor.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
RecordDecl - Represents a struct/union/class.
One of these records is kept for each identifier that is lexed.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
field_range fields() const
Represents binding an expression to a temporary.
detail::InMemoryDirectory::const_iterator I
static bool IsPartOfAST(const CXXRecordDecl *R)
static bool IsStdString(QualType T)
Expr - This represents one expression.
StringRef getName() const
Return the actual identifier string.
Represents a C++ template name within the type system.
static bool IsClangType(const RecordDecl *RD)
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
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.
CHECKER * registerChecker()
Used to register checkers.
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.
TypedefNameDecl * getDecl() const
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)
Base class for declarations which introduce a typedef-name.
The base class of all kinds of template declarations (e.g., class, function, etc.).
detail::InMemoryDirectory::const_iterator E
static bool InNamespace(const Decl *D, StringRef NS)
Check whether the declaration is semantically inside the top-level namespace named by ns...
unsigned getNumArgs() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const T * getAs() const
Member-template getAs<specific type>'.
static bool IsLLVMStringRef(QualType T)
Expr * getArg(unsigned Arg)
Return the specified argument.
Represents a C++ struct/union/class.
static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR, const CheckerBase *Checker)
static bool AllocatesMemory(QualType T)
TemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon, QualType Aliased)
static bool IsClangAttr(const RecordDecl *RD)