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); } } }