CMS 3D CMS Logo

FiniteMathChecker.cc
Go to the documentation of this file.
1 #include "FiniteMathChecker.h"
2 #include <clang/AST/AST.h>
3 #include <clang/AST/ASTConsumer.h>
4 #include <clang/AST/DeclGroup.h>
5 #include <clang/AST/RecursiveASTVisitor.h>
6 #include <clang/AST/Expr.h>
7 
8 #include "CmsSupport.h"
9 #include <iostream>
10 #include <memory>
11 
12 #include <utility>
13 
14 using namespace clang;
15 using namespace clang::ento;
16 using namespace llvm;
17 
18 namespace clangcms {
19 
20  class FMWalkAST : public clang::StmtVisitor<FMWalkAST> {
21  const CheckerBase *Checker;
22  clang::ento::BugReporter &BR;
23  clang::AnalysisDeclContext *AC;
24  const NamedDecl *ND;
25 
26  public:
27  FMWalkAST(const CheckerBase *checker,
28  clang::ento::BugReporter &br,
29  clang::AnalysisDeclContext *ac,
30  const NamedDecl *nd)
31  : Checker(checker), BR(br), AC(ac), ND(nd) {}
32 
33  // Stmt visitor methods.
34  void VisitChildren(clang::Stmt *S);
35  void VisitStmt(clang::Stmt *S) { VisitChildren(S); }
36  void VisitCallExpr(clang::CallExpr *CE);
37  };
38 
39  void FMWalkAST::VisitChildren(clang::Stmt *S) {
40  for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I != E; ++I)
41  if (clang::Stmt *child = *I) {
42  Visit(child);
43  }
44  }
45 
46  void FMWalkAST::VisitCallExpr(clang::CallExpr *CE) {
47  const clang::Expr *Callee = CE->getCallee();
48  const FunctionDecl *FD = CE->getDirectCallee();
49  if (!FD)
50  return;
51 
52  const char *sfile = BR.getSourceManager().getPresumedLoc(CE->getExprLoc()).getFilename();
53  std::string sname(sfile);
55  return;
56 
57  // Get the name of the callee.
58  clang::IdentifierInfo *II = FD->getIdentifier();
59  if (!II) // if no identifier, not a simple C function
60  return;
61 
62  if (!II->isStr("isnan") && !II->isStr("isinf"))
63  return;
64 
65  clang::ento::PathDiagnosticLocation CELoc =
66  clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
67  BugType *BT = new clang::ento::BugType(Checker,
68  "std::isnan / std::isinf does not work when fast-math is used. Please use "
69  "edm::isNotFinite from 'FWCore/Utilities/interface/isFinite.h'",
70  "fastmath plugin");
71  std::unique_ptr<clang::ento::BasicBugReport> report =
72  std::make_unique<clang::ento::BasicBugReport>(*BT, BT->getCheckerName(), CELoc);
73  BR.emitReport(std::move(report));
74  }
75 
76  void FiniteMathChecker::checkASTDecl(const clang::CXXRecordDecl *RD,
77  clang::ento::AnalysisManager &mgr,
78  clang::ento::BugReporter &BR) const {
79  const clang::SourceManager &SM = BR.getSourceManager();
80  const char *sfile = SM.getPresumedLoc(RD->getLocation()).getFilename();
81  if (!support::isCmsLocalFile(sfile))
82  return;
83 
84  for (clang::CXXRecordDecl::method_iterator I = RD->method_begin(), E = RD->method_end(); I != E; ++I) {
85  clang::CXXMethodDecl *MD = llvm::cast<clang::CXXMethodDecl>((*I)->getMostRecentDecl());
86  clang::Stmt *Body = MD->getBody();
87  if (Body) {
88  FMWalkAST walker(this, BR, mgr.getAnalysisDeclContext(MD), MD);
89  walker.Visit(Body);
90  }
91  }
92  }
93 } // namespace clangcms
void VisitStmt(clang::Stmt *S)
clang::AnalysisDeclContext * AC
bool isInterestingLocation(const std::string &d)
FMWalkAST(const CheckerBase *checker, clang::ento::BugReporter &br, clang::AnalysisDeclContext *ac, const NamedDecl *nd)
const NamedDecl * ND
const CheckerBase * Checker
const std::complex< double > I
Definition: I.h:8
clang::ento::BugReporter & BR
bool isCmsLocalFile(const char *file)
def move(src, dest)
Definition: eostools.py:511