clang: lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

19#include "llvm/ADT/SmallString.h"

20#include "llvm/Support/raw_ostream.h"

21

22using namespace clang;

23using namespace ento;

24

25

26

27

28

31 if (!RT)

32 return false;

33

35}

36

37

38

41 if (!ND)

42 return false;

44 if (!II || II->getName() != NS)

45 return false;

46 return isa(ND->getDeclContext());

47}

48

51 T = QT->getNamedType();

52

54 if (!TT)

55 return false;

56

58

60 return false;

61

62 return TD->getName() == "string";

63}

64

67}

68

71}

72

75}

76

79}

80

83 if (!TS)

84 return false;

85

88

90 return false;

91

92 return TD->getName() == "vector";

93}

94

97 if (!TS)

98 return false;

99

102

104 return false;

105

106 return TD->getName() == "SmallVector";

107}

108

109

110

111

112

113

114namespace {

115class StringRefCheckerVisitor : public StmtVisitor {

116 const Decl *DeclWithIssue;

119

120public:

121 StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br,

123 : DeclWithIssue(declWithIssue), BR(br), Checker(checker) {}

124 void VisitChildren(Stmt *S) {

125 for (Stmt *Child : S->children())

126 if (Child)

128 }

129 void VisitStmt(Stmt *S) { VisitChildren(S); }

130 void VisitDeclStmt(DeclStmt *DS);

131private:

132 void VisitVarDecl(VarDecl *VD);

133};

134}

135

138 StringRefCheckerVisitor walker(D, BR, Checker);

140}

141

142void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) {

143 VisitChildren(S);

144

145 for (auto *I : S->decls())

146 if (VarDecl *VD = dyn_cast(I))

147 VisitVarDecl(VD);

148}

149

150void StringRefCheckerVisitor::VisitVarDecl(VarDecl *VD) {

153 return;

154

155

156

158 return;

160 if (!Ex1)

161 return;

164 return;

166 if (!Ex3)

167 return;

170 return;

172 if (!Ex5)

173 return;

176 return;

177

178

179 const char *desc = "StringRef should not be bound to temporary "

180 "std::string that it outlives";

184 VDLoc, Init->getSourceRange());

185}

186

187

188

189

190

191

194}

195

196

199 return true;

200

201 for (const auto &BS : R->bases()) {

204 CXXRecordDecl *baseD = cast(baseT->getDecl());

206 return true;

207 }

208 }

209

210 return false;

211}

212

213namespace {

214class ASTFieldVisitor {

219

220public:

223 : Root(root), BR(br), Checker(checker) {}

224

227};

228}

229

233 return;

234

235 for (auto *I : R->fields()) {

236 ASTFieldVisitor walker(R, BR, Checker);

237 walker.Visit(I);

238 }

239}

240

241void ASTFieldVisitor::Visit(FieldDecl *D) {

242 FieldChain.push_back(D);

243

245

247 ReportError(T);

248

251 for (auto *I : RD->fields())

252 Visit(I);

253 }

254

255 FieldChain.pop_back();

256}

257

258void ASTFieldVisitor::ReportError(QualType T) {

260 llvm::raw_svector_ostream os(buf);

261

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: ";

266 bool isFirst = true;

268 E=FieldChain.end(); I!=E; ++I) {

269 if (!isFirst)

270 os << '.';

271 else

272 isFirst = false;

273 os << (*I)->getName();

274 }

275 }

276 os << " (type " << FieldChain.back()->getType() << ")";

277

278

279

280

281

282

283

284

288 "LLVM Conventions", os.str(), L);

289}

290

291

292

293

294

295namespace {

296class LLVMConventionsChecker : public Checker<

297 check::ASTDecl,

298 check::ASTCodeBody > {

299public:

304 }

305

309 }

310};

311}

312

313void ento::registerLLVMConventionsChecker(CheckerManager &mgr) {

315}

316

317bool ento::shouldRegisterLLVMConventionsChecker(const CheckerManager &mgr) {

318 return true;

319}

Defines the C++ template declaration subclasses.

static bool IsStdVector(QualType T)

static bool IsClangType(const RecordDecl *RD)

static bool AllocatesMemory(QualType T)

static bool IsClangStmt(const RecordDecl *RD)

static bool InNamespace(const Decl *D, StringRef NS)

Check whether the declaration is semantically inside the top-level namespace named by ns.

static bool IsClangAttr(const RecordDecl *RD)

static bool IsStdString(QualType T)

static bool IsClangDecl(const RecordDecl *RD)

static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR, const CheckerBase *Checker)

static bool IsPartOfAST(const CXXRecordDecl *R)

static bool IsSmallVector(QualType T)

static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR, const CheckerBase *Checker)

static bool IsLLVMStringRef(QualType T)

Represents binding an expression to a temporary.

Represents a call to a C++ constructor.

Expr * getArg(unsigned Arg)

Return the specified argument.

unsigned getNumArgs() const

Return the number of arguments to the constructor call.

Represents a C++ struct/union/class.

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

Decl - This represents one declaration (or definition), e.g.

bool isInStdNamespace() const

virtual Stmt * getBody() const

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

DeclContext * getDeclContext()

Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...

Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...

This represents one expression.

Represents a member of a struct/union/class.

const Expr * getSubExpr() const

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

Represent a C++ namespace.

A (possibly-)qualified type.

Represents a struct/union/class.

field_range fields() const

RecordDecl * getDefinition() const

Returns the RecordDecl that actually defines this struct/union/class.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RetTy Visit(PTR(Stmt) S, ParamTys... P)

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

Stmt - This represents one statement.

bool isCompleteDefinition() const

Return true if this decl has its body fully specified.

The base class of all kinds of template declarations (e.g., class, function, etc.).

Represents a C++ template name within the type system.

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

Represents a type template specialization; the template must be a class template, a type alias templa...

TemplateName getTemplateName() const

Retrieve the name of the template that we are specializing.

const T * getAs() const

Member-template getAs'.

Base class for declarations which introduce a typedef-name.

TypedefNameDecl * getDecl() const

Represents a variable declaration or definition.

const Expr * getInit() const

BugReporter is a utility class for generating PathDiagnostics for analysis.

const SourceManager & getSourceManager()

void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})

CHECKER * registerChecker(AT &&... Args)

Used to register checkers.

static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)

Create a location for the beginning of the declaration.

The JSON file list parser is used to communicate input to InstallAPI.

const FunctionProtoType * T

llvm::StringRef getAsString(SyncScope S)