File indexing completed on 2024-04-06 12:31:50
0001 #include "ESRecordGetChecker.h"
0002 using namespace clang;
0003 using namespace ento;
0004 using namespace llvm;
0005
0006 namespace clangcms {
0007
0008 class ESRWalker : public clang::StmtVisitor<ESRWalker> {
0009 const CheckerBase *Checker;
0010 clang::ento::BugReporter &BR;
0011 clang::AnalysisDeclContext *AC;
0012
0013 public:
0014 ESRWalker(const CheckerBase *checker, clang::ento::BugReporter &br, clang::AnalysisDeclContext *ac)
0015 : Checker(checker), BR(br), AC(ac) {}
0016
0017 void VisitChildren(clang::Stmt *S);
0018 void VisitStmt(clang::Stmt *S) { VisitChildren(S); }
0019 void VisitCXXMemberCallExpr(clang::CXXMemberCallExpr *CE);
0020 };
0021
0022 void ESRWalker::VisitChildren(clang::Stmt *S) {
0023 for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I != E; ++I)
0024 if (clang::Stmt *child = *I) {
0025 Visit(child);
0026 }
0027 }
0028
0029 void ESRWalker::VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
0030 LangOptions LangOpts;
0031 LangOpts.CPlusPlus = true;
0032 PrintingPolicy Policy(LangOpts);
0033 const Decl *D = AC->getDecl();
0034 std::string dname = "";
0035 if (const NamedDecl *ND = llvm::dyn_cast_or_null<NamedDecl>(D))
0036 dname = ND->getQualifiedNameAsString();
0037 if (dname == "edm::eventsetup::EventSetupRecord::get")
0038 return;
0039 CXXMethodDecl *MD = CE->getMethodDecl();
0040 if (!MD)
0041 return;
0042 std::string mname = MD->getQualifiedNameAsString();
0043 if (mname == "edm::eventsetup::EventSetupRecord::get") {
0044 std::string mname = MD->getQualifiedNameAsString();
0045 llvm::SmallString<100> buf;
0046 llvm::raw_svector_ostream os(buf);
0047 os << "function '";
0048 llvm::dyn_cast<FunctionDecl>(D)->getNameForDiagnostic(os, Policy, true);
0049 os << "' ";
0050 os << "calls function '";
0051 MD->getNameForDiagnostic(os, Policy, true);
0052 for (auto I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
0053 QualType QT = (*I)->getType();
0054 std::string qtname = QT.getAsString();
0055 os << "' with argument of type '" << qtname;
0056 }
0057 os << "'";
0058 os << ". Direct call of function EventSetupRecord::get(ESHandle&) is deprecated and should be replaced with a "
0059 "call to EventSetup::getHandle(ESGetToken&). To use ESGetToken see "
0060 "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideHowToGetDataFromES#In_ED_module To get data with "
0061 "the token see "
0062 "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideHowToGetDataFromES#Getting_data_from_EventSetup_wit";
0063 PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
0064 BugType *BT = new BugType(Checker, "EventSetupRecord::get function called", "Deprecated API");
0065 std::unique_ptr<BasicBugReport> R = std::make_unique<BasicBugReport>(*BT, llvm::StringRef(os.str()), CELoc);
0066 R->addRange(CE->getSourceRange());
0067 BR.emitReport(std::move(R));
0068 }
0069 }
0070
0071 void ESRGetChecker::checkASTDecl(const CXXMethodDecl *MD, AnalysisManager &mgr, BugReporter &BR) const {
0072 const SourceManager &SM = BR.getSourceManager();
0073 PathDiagnosticLocation DLoc = PathDiagnosticLocation::createBegin(MD, SM);
0074 if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0075 return;
0076 if (!MD->doesThisDeclarationHaveABody())
0077 return;
0078 ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(MD));
0079 walker.Visit(MD->getBody());
0080 return;
0081 }
0082
0083 void ESRGetChecker::checkASTDecl(const FunctionTemplateDecl *TD, AnalysisManager &mgr, BugReporter &BR) const {
0084 const clang::SourceManager &SM = BR.getSourceManager();
0085 clang::ento::PathDiagnosticLocation DLoc = clang::ento::PathDiagnosticLocation::createBegin(TD, SM);
0086 if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0087 return;
0088
0089 for (auto I = TD->spec_begin(), E = TD->spec_end(); I != E; ++I) {
0090 if (I->doesThisDeclarationHaveABody()) {
0091 ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(*I));
0092 walker.Visit(I->getBody());
0093 }
0094 }
0095 return;
0096 }
0097
0098 void ESRGetChecker::checkASTDecl(const FunctionDecl *FD, AnalysisManager &mgr, BugReporter &BR) const {
0099 const SourceManager &SM = BR.getSourceManager();
0100 PathDiagnosticLocation DLoc = PathDiagnosticLocation::createBegin(FD, SM);
0101 if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0102 return;
0103 if (!FD->doesThisDeclarationHaveABody())
0104 return;
0105 ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(FD));
0106 walker.Visit(FD->getBody());
0107 return;
0108 }
0109
0110 }