void ConstCastAwayChecker::checkPreStmt(const clang::ExplicitCastExpr *CE, clang::ento::CheckerContext &C) const { if (! ( clang::CStyleCastExpr::classof(CE) || clang::CXXConstCastExpr::classof(CE) )) return; const Expr * SE = CE->getSubExpr(); const CXXRecordDecl * CRD = nullptr; std::string cname; if (SE->getType()->isPointerType()) CRD = SE->getType()->getPointeeCXXRecordDecl(); else CRD = SE->getType()->getAsCXXRecordDecl(); if (CRD) cname = CRD->getQualifiedNameAsString(); clang::ASTContext &Ctx = C.getASTContext(); clang::QualType OrigTy = Ctx.getCanonicalType(SE->getType()); clang::QualType ToTy = Ctx.getCanonicalType(CE->getType()); if ( support::isConst( OrigTy ) && ! support::isConst(ToTy) ) { if ( clang::ento::ExplodedNode *errorNode = C.generateErrorNode()) { if (!BT) BT.reset(new clang::ento::BugType(this,"const cast away","ConstThreadSafety")); std::string buf; llvm::raw_string_ostream os(buf); os << "const qualifier was removed via a cast, this may result in thread-unsafe code."; std::unique_ptr<clang::ento::BugReport> R = llvm::make_unique<clang::ento::BugReport>(*BT, os.str(), errorNode); R->addRange(CE->getSourceRange()); if ( ! m_exception.reportConstCastAway( *R, C ) ) return; C.emitReport(std::move(R)); if (cname == "") return; std::string tname ="constcastaway-checker.txt.unsorted"; std::string tolog ="flagged class '"+cname+"' const qualifier cast away"; support::writeLog(tolog,tname); } } }
void ConstCastChecker::checkPreStmt(const clang::CXXConstCastExpr *CE, clang::ento::CheckerContext &C) const { const Expr * SE = CE->getSubExprAsWritten(); const CXXRecordDecl * CRD = 0; if (SE->getType()->isPointerType()) CRD = SE->getType()->getPointeeCXXRecordDecl(); else CRD = SE->getType()->getAsCXXRecordDecl(); if (CRD) { std::string cname = CRD->getQualifiedNameAsString(); if (! support::isDataClass(cname) ) return; } if (clang::ento::ExplodedNode *errorNode = C.generateSink()) { if (!BT) BT.reset(new clang::ento::BugType(this,"const_cast used on a pointer to a data class ", "ThreadSafety")); clang::ento::BugReport *R = new clang::ento::BugReport(*BT, "const_cast was used on a pointer to a data class ", errorNode); R->addRange(CE->getSourceRange()); if ( ! m_exception.reportConstCast( *R, C ) ) return; C.emitReport(R); } }
void ConstCastAwayChecker::checkPreStmt(const clang::ExplicitCastExpr *CE, clang::ento::CheckerContext &C) const { const clang::Expr *E = CE->getSubExpr(); clang::ASTContext &Ctx = C.getASTContext(); clang::QualType OrigTy = Ctx.getCanonicalType(E->getType()); clang::QualType ToTy = Ctx.getCanonicalType(CE->getType()); if ( support::isConst( OrigTy ) && ! support::isConst(ToTy) ) { if ( clang::ento::ExplodedNode *errorNode = C.generateSink()) { if (!BT) BT.reset( new clang::ento::BugType("const cast away", "ThreadSafety")); clang::ento::BugReport *R = new clang::ento::BugReport(*BT, "const qualifier was removed via a cast, this may result in thread-unsafe code.", errorNode); R->addRange(CE->getSourceRange()); if ( ! m_exception.reportConstCastAway( *R, C ) ) return; C.emitReport(R); } } }