Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-08 23:10:07

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     assert(D);
0035     std::string dname = "";
0036     if (const NamedDecl *ND = llvm::dyn_cast_or_null<NamedDecl>(D))
0037       dname = ND->getQualifiedNameAsString();
0038     if (dname == "edm::eventsetup::EventSetupRecord::get")
0039       return;
0040     CXXMethodDecl *MD = CE->getMethodDecl();
0041     if (!MD)
0042       return;
0043     std::string mname = MD->getQualifiedNameAsString();
0044     if (mname == "edm::eventsetup::EventSetupRecord::get") {
0045       std::string mname = MD->getQualifiedNameAsString();
0046       llvm::SmallString<100> buf;
0047       llvm::raw_svector_ostream os(buf);
0048       os << "function '";
0049       assert(llvm::dyn_cast<FunctionDecl>(D));
0050       llvm::dyn_cast<FunctionDecl>(D)->getNameForDiagnostic(os, Policy, true);
0051       os << "' ";
0052       os << "calls function '";
0053       MD->getNameForDiagnostic(os, Policy, true);
0054       for (auto I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
0055         QualType QT = (*I)->getType();
0056         std::string qtname = QT.getAsString();
0057         os << "' with argument of type '" << qtname;
0058       }
0059       os << "'";
0060       os << ". Direct call of function EventSetupRecord::get(ESHandle&) is deprecated and should be replaced with a "
0061             "call to EventSetup::getHandle(ESGetToken&). To use ESGetToken see "
0062             "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideHowToGetDataFromES#In_ED_module To get data with "
0063             "the token see "
0064             "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideHowToGetDataFromES#Getting_data_from_EventSetup_wit";
0065       PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
0066       BugType *BT = new BugType(Checker, "EventSetupRecord::get function called", "Deprecated API");
0067       std::unique_ptr<BasicBugReport> R = std::make_unique<BasicBugReport>(*BT, llvm::StringRef(os.str()), CELoc);
0068       R->addRange(CE->getSourceRange());
0069       BR.emitReport(std::move(R));
0070     }
0071   }
0072 
0073   void ESRGetChecker::checkASTDecl(const CXXMethodDecl *MD, AnalysisManager &mgr, BugReporter &BR) const {
0074     const SourceManager &SM = BR.getSourceManager();
0075     PathDiagnosticLocation DLoc = PathDiagnosticLocation::createBegin(MD, SM);
0076     if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0077       return;
0078     if (!MD->doesThisDeclarationHaveABody())
0079       return;
0080     ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(MD));
0081     walker.Visit(MD->getBody());
0082     return;
0083   }
0084 
0085   void ESRGetChecker::checkASTDecl(const FunctionTemplateDecl *TD, AnalysisManager &mgr, BugReporter &BR) const {
0086     const clang::SourceManager &SM = BR.getSourceManager();
0087     clang::ento::PathDiagnosticLocation DLoc = clang::ento::PathDiagnosticLocation::createBegin(TD, SM);
0088     if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0089       return;
0090 
0091     for (auto I = TD->spec_begin(), E = TD->spec_end(); I != E; ++I) {
0092       if (I->doesThisDeclarationHaveABody()) {
0093         ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(*I));
0094         walker.Visit(I->getBody());
0095       }
0096     }
0097     return;
0098   }
0099 
0100   void ESRGetChecker::checkASTDecl(const FunctionDecl *FD, AnalysisManager &mgr, BugReporter &BR) const {
0101     const SourceManager &SM = BR.getSourceManager();
0102     PathDiagnosticLocation DLoc = PathDiagnosticLocation::createBegin(FD, SM);
0103     if (SM.isInSystemHeader(DLoc.asLocation()) || SM.isInExternCSystemHeader(DLoc.asLocation()))
0104       return;
0105     if (!FD->doesThisDeclarationHaveABody())
0106       return;
0107     ESRWalker walker(this, BR, mgr.getAnalysisDeclContext(FD));
0108     walker.Visit(FD->getBody());
0109     return;
0110   }
0111 
0112 }  // namespace clangcms