File indexing completed on 2024-04-06 12:31:50
0001
0002
0003
0004
0005
0006
0007 #include <clang/AST/Attr.h>
0008 #include <clang/AST/ExprCXX.h>
0009 #include <clang/AST/ParentMap.h>
0010
0011 #include <memory>
0012
0013 #include "ConstCastChecker.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 ConstCastChecker::checkPreStmt(const clang::CXXConstCastExpr *CE, clang::ento::CheckerContext &C) const {
0023 auto P = C.getCurrentAnalysisDeclContext()->getParentMap().getParent(CE);
0024 while (P && !(isa<AttributedStmt>(P) || isa<DeclStmt>(P)) &&
0025 C.getCurrentAnalysisDeclContext()->getParentMap().hasParent(P)) {
0026 P = C.getCurrentAnalysisDeclContext()->getParentMap().getParent(P);
0027 }
0028 if (P && isa<AttributedStmt>(P)) {
0029 const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(P);
0030 if (AS && (hasSpecificAttr<CMSSaAllowAttr>(AS->getAttrs()) || hasSpecificAttr<CMSThreadSafeAttr>(AS->getAttrs())))
0031 return;
0032 }
0033 if (P && isa<DeclStmt>(P)) {
0034 const DeclStmt *DS = dyn_cast_or_null<DeclStmt>(P);
0035 if (DS) {
0036 for (auto D : DS->decls()) {
0037 if (hasSpecificAttr<CMSSaAllowAttr>(D->getAttrs()) || hasSpecificAttr<CMSThreadSafeAttr>(D->getAttrs())) {
0038 return;
0039 }
0040 }
0041 }
0042 }
0043
0044 const Expr *SE = CE->getSubExprAsWritten();
0045 const CXXRecordDecl *CRD = nullptr;
0046 std::string cname;
0047 if (SE->getType()->isPointerType())
0048 CRD = SE->getType()->getPointeeCXXRecordDecl();
0049 else
0050 CRD = SE->getType()->getAsCXXRecordDecl();
0051 if (CRD)
0052 cname = CRD->getQualifiedNameAsString();
0053 if (clang::ento::ExplodedNode *errorNode = C.generateErrorNode()) {
0054 if (!BT)
0055 BT = std::make_unique<clang::ento::BugType>(this, "const_cast used on pointer to class", "ConstThreadSafety");
0056 std::string buf;
0057 llvm::raw_string_ostream os(buf);
0058 os << "const_cast was used, this may result in thread-unsafe code.";
0059 std::unique_ptr<clang::ento::PathSensitiveBugReport> PSBR =
0060 std::make_unique<clang::ento::PathSensitiveBugReport>(*BT, llvm::StringRef(os.str()), errorNode);
0061 PSBR->addRange(CE->getSourceRange());
0062 if (!m_exception.reportConstCast(*PSBR, C))
0063 return;
0064 C.emitReport(std::move(PSBR));
0065 if (cname.empty())
0066 return;
0067 std::string tname = "constcast-checker.txt.unsorted";
0068 std::string tolog = "flagged class '" + cname + "' const_cast used ";
0069 support::writeLog(tolog, tname);
0070 }
0071 }
0072
0073 }