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))
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) {
127 for (
Stmt *Child : S->children())
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,
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) {}
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() <<
")";
289 FieldChain.front(), BR.getSourceManager());
290 BR.EmitBasicReport(Root,
Checker,
"AST node allocates heap memory",
291 "LLVM Conventions", os.str(), L);
299 class LLVMConventionsChecker :
public Checker<
300 check::ASTDecl<CXXRecordDecl>,
301 check::ASTCodeBody > {
Represents a type that was referred to using an elaborated type keyword, e.g., struct S...
StringRef getName() const
static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR, const CheckerBase *Checker)
IdentifierInfo * getIdentifier() const
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
Defines the C++ template declaration subclasses.
bool isInStdNamespace() const
const Expr * getInit() const
NamespaceDecl - Represent a C++ namespace.
Represents a call to a C++ constructor.
bool isCompleteDefinition() const
TemplateName getTemplateName() const
Retrieve the name of the template that we are specializing.
field_range fields() const
Represents binding an expression to a temporary.
static bool IsPartOfAST(const CXXRecordDecl *R)
static bool IsStdString(QualType T)
StringRef getName() const
Return the actual identifier string.
DeclContext * getDeclContext()
Represents a C++ template name within the type system.
static bool IsClangType(const RecordDecl *RD)
RecordDecl * getDefinition() const
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)
virtual Stmt * getBody() const
TypedefNameDecl * getDecl() const
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.).
static bool InNamespace(const Decl *D, StringRef NS)
unsigned getNumArgs() const
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)
Represents a type template specialization; the template must be a class template, a type alias templa...
static bool IsClangAttr(const RecordDecl *RD)