예제 #1
0
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);
      }
   }
}
예제 #2
0
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);
	}

}
예제 #3
0
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);
		}
	}
}