Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:32:04

0001 //== ConstCastAwayChecker.cpp - Checks for removed const qualfiers --------------*- C++ -*--==//
0002 //
0003 // Check in a generic way if an explicit cast removes a const qualifier.
0004 //
0005 // by Thomas Hauth [ Thomas.Hauth@cern.ch ]
0006 //
0007 //===----------------------------------------------------------------------===//
0008 #include <clang/AST/ExprCXX.h>
0009 #include <clang/AST/Attr.h>
0010 
0011 #include <memory>
0012 
0013 #include "ConstCastAwayChecker.h"
0014 #include "CmsSupport.h"
0015 
0016 using namespace clang;
0017 using namespace clang::ento;
0018 using namespace llvm;
0019 
0020 namespace clangcms {
0021 
0022   void ConstCastAwayChecker::checkPreStmt(const clang::ExplicitCastExpr *CE, clang::ento::CheckerContext &C) const {
0023     if (!(clang::CStyleCastExpr::classof(CE) || clang::CXXConstCastExpr::classof(CE)))
0024       return;
0025     const Expr *SE = CE->getSubExpr();
0026     const CXXRecordDecl *CRD = nullptr;
0027     std::string cname;
0028     if (SE->getType()->isPointerType())
0029       CRD = SE->getType()->getPointeeCXXRecordDecl();
0030     else
0031       CRD = SE->getType()->getAsCXXRecordDecl();
0032 
0033     if (CRD)
0034       cname = CRD->getQualifiedNameAsString();
0035 
0036     clang::ASTContext &Ctx = C.getASTContext();
0037     clang::QualType OrigTy = Ctx.getCanonicalType(SE->getType());
0038     clang::QualType ToTy = Ctx.getCanonicalType(CE->getType());
0039 
0040     if (support::isConst(OrigTy) && !support::isConst(ToTy)) {
0041       if (clang::ento::ExplodedNode *errorNode = C.generateErrorNode()) {
0042         if (!BT)
0043           BT = std::make_unique<clang::ento::BugType>(this, "const cast away", "ConstThreadSafety");
0044         std::string buf;
0045         llvm::raw_string_ostream os(buf);
0046         os << "const qualifier was removed via a cast, this may result in thread-unsafe code.";
0047         std::unique_ptr<clang::ento::PathSensitiveBugReport> PSBR =
0048             std::make_unique<clang::ento::PathSensitiveBugReport>(*BT, llvm::StringRef(os.str()), errorNode);
0049         std::unique_ptr<clang::ento::BasicBugReport> R =
0050             std::make_unique<clang::ento::BasicBugReport>(*BT, llvm::StringRef(os.str()), PSBR->getLocation());
0051         R->addRange(CE->getSourceRange());
0052         if (!m_exception.reportConstCastAway(*R, C))
0053           return;
0054         C.emitReport(std::move(R));
0055         if (cname.empty())
0056           return;
0057         std::string tname = "constcastaway-checker.txt.unsorted";
0058         std::string tolog = "flagged class '" + cname + "' const qualifier cast away";
0059         support::writeLog(tolog, tname);
0060       }
0061     }
0062   }
0063 
0064 }  // namespace clangcms