LLVMConventionsChecker.cpp (226633) | LLVMConventionsChecker.cpp (234353) |
---|---|
1//=== LLVMConventionsChecker.cpp - Check LLVM codebase conventions ---*- C++ -*- 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This defines LLVMConventionsChecker, a bunch of small little checks 11// for checking specific coding conventions in the LLVM/Clang codebase. 12// 13//===----------------------------------------------------------------------===// 14 15#include "ClangSACheckers.h" 16#include "clang/StaticAnalyzer/Core/Checker.h" 17#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/StmtVisitor.h" | 1//=== LLVMConventionsChecker.cpp - Check LLVM codebase conventions ---*- C++ -*- 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This defines LLVMConventionsChecker, a bunch of small little checks 11// for checking specific coding conventions in the LLVM/Clang codebase. 12// 13//===----------------------------------------------------------------------===// 14 15#include "ClangSACheckers.h" 16#include "clang/StaticAnalyzer/Core/Checker.h" 17#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/StmtVisitor.h" |
20#include <string> 21#include "llvm/ADT/StringRef.h" | 20#include "llvm/ADT/SmallString.h" |
22 23using namespace clang; 24using namespace ento; 25 26//===----------------------------------------------------------------------===// 27// Generic type checking routines. 28//===----------------------------------------------------------------------===// 29 --- 81 unchanged lines hidden (view full) --- 111//===----------------------------------------------------------------------===// 112// CHECK: a StringRef should not be bound to a temporary std::string whose 113// lifetime is shorter than the StringRef's. 114//===----------------------------------------------------------------------===// 115 116namespace { 117class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> { 118 BugReporter &BR; | 21 22using namespace clang; 23using namespace ento; 24 25//===----------------------------------------------------------------------===// 26// Generic type checking routines. 27//===----------------------------------------------------------------------===// 28 --- 81 unchanged lines hidden (view full) --- 110//===----------------------------------------------------------------------===// 111// CHECK: a StringRef should not be bound to a temporary std::string whose 112// lifetime is shorter than the StringRef's. 113//===----------------------------------------------------------------------===// 114 115namespace { 116class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> { 117 BugReporter &BR; |
118 const Decl *DeclWithIssue; |
|
119public: | 119public: |
120 StringRefCheckerVisitor(BugReporter &br) : BR(br) {} | 120 StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br) 121 : BR(br), DeclWithIssue(declWithIssue) {} |
121 void VisitChildren(Stmt *S) { 122 for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ; 123 I != E; ++I) 124 if (Stmt *child = *I) 125 Visit(child); 126 } 127 void VisitStmt(Stmt *S) { VisitChildren(S); } 128 void VisitDeclStmt(DeclStmt *DS); 129private: 130 void VisitVarDecl(VarDecl *VD); 131}; 132} // end anonymous namespace 133 134static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) { | 122 void VisitChildren(Stmt *S) { 123 for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ; 124 I != E; ++I) 125 if (Stmt *child = *I) 126 Visit(child); 127 } 128 void VisitStmt(Stmt *S) { VisitChildren(S); } 129 void VisitDeclStmt(DeclStmt *DS); 130private: 131 void VisitVarDecl(VarDecl *VD); 132}; 133} // end anonymous namespace 134 135static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) { |
135 StringRefCheckerVisitor walker(BR); | 136 StringRefCheckerVisitor walker(D, BR); |
136 walker.Visit(D->getBody()); 137} 138 139void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) { 140 VisitChildren(S); 141 142 for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();I!=E; ++I) 143 if (VarDecl *VD = dyn_cast<VarDecl>(*I)) --- 28 unchanged lines hidden (view full) --- 172 if (!Ex6 || !IsStdString(Ex6->getType())) 173 return; 174 175 // Okay, badness! Report an error. 176 const char *desc = "StringRef should not be bound to temporary " 177 "std::string that it outlives"; 178 PathDiagnosticLocation VDLoc = 179 PathDiagnosticLocation::createBegin(VD, BR.getSourceManager()); | 137 walker.Visit(D->getBody()); 138} 139 140void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) { 141 VisitChildren(S); 142 143 for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();I!=E; ++I) 144 if (VarDecl *VD = dyn_cast<VarDecl>(*I)) --- 28 unchanged lines hidden (view full) --- 173 if (!Ex6 || !IsStdString(Ex6->getType())) 174 return; 175 176 // Okay, badness! Report an error. 177 const char *desc = "StringRef should not be bound to temporary " 178 "std::string that it outlives"; 179 PathDiagnosticLocation VDLoc = 180 PathDiagnosticLocation::createBegin(VD, BR.getSourceManager()); |
180 BR.EmitBasicReport(desc, "LLVM Conventions", desc, | 181 BR.EmitBasicReport(DeclWithIssue, desc, "LLVM Conventions", desc, |
181 VDLoc, Init->getSourceRange()); 182} 183 184//===----------------------------------------------------------------------===// 185// CHECK: Clang AST nodes should not have fields that can allocate 186// memory. 187//===----------------------------------------------------------------------===// 188 --- 59 unchanged lines hidden (view full) --- 248 I != E; ++I) 249 Visit(*I); 250 } 251 252 FieldChain.pop_back(); 253} 254 255void ASTFieldVisitor::ReportError(QualType T) { | 182 VDLoc, Init->getSourceRange()); 183} 184 185//===----------------------------------------------------------------------===// 186// CHECK: Clang AST nodes should not have fields that can allocate 187// memory. 188//===----------------------------------------------------------------------===// 189 --- 59 unchanged lines hidden (view full) --- 249 I != E; ++I) 250 Visit(*I); 251 } 252 253 FieldChain.pop_back(); 254} 255 256void ASTFieldVisitor::ReportError(QualType T) { |
256 llvm::SmallString<1024> buf; | 257 SmallString<1024> buf; |
257 llvm::raw_svector_ostream os(buf); 258 259 os << "AST class '" << Root->getName() << "' has a field '" 260 << FieldChain.front()->getName() << "' that allocates heap memory"; 261 if (FieldChain.size() > 1) { 262 os << " via the following chain: "; 263 bool isFirst = true; 264 for (SmallVectorImpl<FieldDecl*>::iterator I=FieldChain.begin(), --- 12 unchanged lines hidden (view full) --- 277 // class. This is suboptimal, but at least scan-build will merge 278 // duplicate HTML reports. In the future we need a unified way of merging 279 // duplicate reports across translation units. For C++ classes we cannot 280 // just report warnings when we see an out-of-line method definition for a 281 // class, as that heuristic doesn't always work (the complete definition of 282 // the class may be in the header file, for example). 283 PathDiagnosticLocation L = PathDiagnosticLocation::createBegin( 284 FieldChain.front(), BR.getSourceManager()); | 258 llvm::raw_svector_ostream os(buf); 259 260 os << "AST class '" << Root->getName() << "' has a field '" 261 << FieldChain.front()->getName() << "' that allocates heap memory"; 262 if (FieldChain.size() > 1) { 263 os << " via the following chain: "; 264 bool isFirst = true; 265 for (SmallVectorImpl<FieldDecl*>::iterator I=FieldChain.begin(), --- 12 unchanged lines hidden (view full) --- 278 // class. This is suboptimal, but at least scan-build will merge 279 // duplicate HTML reports. In the future we need a unified way of merging 280 // duplicate reports across translation units. For C++ classes we cannot 281 // just report warnings when we see an out-of-line method definition for a 282 // class, as that heuristic doesn't always work (the complete definition of 283 // the class may be in the header file, for example). 284 PathDiagnosticLocation L = PathDiagnosticLocation::createBegin( 285 FieldChain.front(), BR.getSourceManager()); |
285 BR.EmitBasicReport("AST node allocates heap memory", "LLVM Conventions", | 286 BR.EmitBasicReport(Root, "AST node allocates heap memory", "LLVM Conventions", |
286 os.str(), L); 287} 288 289//===----------------------------------------------------------------------===// 290// LLVMConventionsChecker 291//===----------------------------------------------------------------------===// 292 293namespace { --- 20 unchanged lines hidden --- | 287 os.str(), L); 288} 289 290//===----------------------------------------------------------------------===// 291// LLVMConventionsChecker 292//===----------------------------------------------------------------------===// 293 294namespace { --- 20 unchanged lines hidden --- |