예제 #1
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)) {
            clang::ento::ExplodedNode* errorNode = C.addTransition();
            if (errorNode) {
               const char* msg = "[sas.ThreadSafety.ConstCastAwayChecker]const qualifier was removed via a cast, this may result in thread-unsafe code.";
               Report(CE, msg, C);
            }
         }
      }
예제 #2
0
bool CmsException::reportConstCast( const clang::ento::BugReport &R,
		clang::ento::CheckerContext &C) const 
{
		clang::ento::BugReporter &BR = C.getBugReporter();
          	const clang::SourceManager &SM = BR.getSourceManager();
		clang::ento::PathDiagnosticLocation const& path = R.getLocation(SM);
	 	return reportGeneral ( path, BR );
}
예제 #3
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);
      }
   }
}
예제 #4
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);
	}

}
예제 #5
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);
		}
	}
}
void TypeConfusionChecker::checkPreStmt(const clang::CastExpr *CE,
                                        clang::ento::CheckerContext &C) const {
  if (isa<ImplicitCastExpr>(CE))
    return;

  DEBUG_PRINT("Explicit cast expression");
//  CE->dump();

  const auto *E = CE->getSubExpr()->IgnoreParenImpCasts();
  if (!isa<DeclRefExpr>(E))
    return;

  DEBUG_PRINT("Found declref expr");

  ProgramStateRef State = C.getState();
  const ValueDecl *VD = cast<DeclRefExpr>(E)->getDecl();
  const QualType *QT = State->get<TypeMap>(VD);

  if (!QT)
    return;

  DEBUG_PRINT("Obtained value from key");

  // Compare Cast To type to T
  if (!isa<ExplicitCastExpr>(CE))
    return;

  const Type *castTo = cast<ExplicitCastExpr>(CE)->getTypeAsWritten().getTypePtr();

  std::string declName, Message, castFromTyString, castToTyString;
  castToTyString = castTo->getCanonicalTypeInternal().getAsString();
  castFromTyString = QT->getAsString();

  if (castToTyString.compare(castFromTyString) == 0)
    return;

  DEBUG_PRINT("Type comparison failed");

  if (isa<NamedDecl>(VD))
      declName = cast<NamedDecl>(VD)->getQualifiedNameAsString();

  Message = declName + " is unsafely cast from " + castFromTyString + " to " +
			castToTyString;

  reportBug(C, CE->getSourceRange(), Message, declName);
}
예제 #7
0
 void PtrCastWinChecker::checkPreStmt(const clang::CStyleCastExpr* CE, clang::ento::CheckerContext& C) const
 {
    if (clang::CK_PointerToIntegral != CE->getCastKind()) return;
    auto subExpr = CE->getSubExpr();
    auto& Ctx = C.getASTContext();
    clang::QualType fromQType = Ctx.getCanonicalType(subExpr->getType());
    clang::QualType toQType = Ctx.getCanonicalType(CE->getType());
    if (fromQType->isPointerType() || fromQType->isArrayType()) {
       auto toType = toQType.getTypePtr();
       // Case one: the toType is a builtin and not a long long
       if (toType->isSpecificBuiltinType(clang::BuiltinType::Long) ||
           toType->isSpecificBuiltinType(clang::BuiltinType::ULong)){
           std::string r = "[sas.CodingConventions.ROOT.PtrCastWinChecker] Casting pointers to integer types which are not (unsigned) long long (in this case a ";
           r+=toQType.getAsString ();
           r+=") is wrong on Windows 64 bits. ";
           Report(CE, r.c_str(), C);
       }
    }
 }
예제 #8
0
void getParamDumper::analyzerEval(const clang::CallExpr *CE, clang::ento::CheckerContext &C) const {

  if ( ! C.getSourceManager().isInMainFile(CE->getExprLoc()) ) return;

  const FunctionDecl * FD = CE->getDirectCallee();

  if (!FD) return;

    std::string mname = support::getQualifiedName(*FD);
    const char *sfile=C.getSourceManager().getPresumedLoc(CE->getExprLoc()).getFilename();
    std::string sname(sfile);
    if ( ! support::isInterestingLocation(sname) ) return;
    std::string mdname;
    const FunctionDecl * MD = C.getCurrentAnalysisDeclContext()->getDecl()->getAsFunction();
    if (!MD) return;
    mdname = MD->getQualifiedNameAsString();
    for ( unsigned I=0, E=MD->getNumParams(); I != E; ++I) {
             std::string ps = "const class edm::ParameterSet ";
             std::string ups = "const class edm::UntrackedParameterSet ";
             std::string pname = MD->getParamDecl(I)->getQualifiedNameAsString();
             std::string qname = MD->getParamDecl(I)->getType().getCanonicalType().getAsString();
//             if (qname.substr(0,ps.length()) == ps || qname.substr(0,ups.length()) == ups) {
                  std::string buf;
                  llvm::raw_string_ostream os(buf);
                  os << "in function decl '"<< mdname << "' with parameter '"<< qname << " " << pname <<"'\n";
//                 }
         }
    const CXXMemberCallExpr * CXE = llvm::dyn_cast_or_null<CXXMemberCallExpr>(CE);
    if (!CXE) return;
    const Expr * IOA = CXE->getImplicitObjectArgument();
    std::string tname = "getparam-dumper.txt.unsorted";
    std::string gp = "edm::ParameterSet::getParameter";
    std::string gup = "edm::ParameterSet::getUntrackedParameter";
    if (mname.substr(0,gp.length()) == gp || mname.substr(0,gup.length()) == gup ) {
         std::string buf;
         llvm::raw_string_ostream os(buf);
         os << "in function decl '" << mdname << "' member function call '";
         clang::LangOptions LangOpts;
         LangOpts.CPlusPlus = true;
         clang::PrintingPolicy Policy(LangOpts);
         os << support::getQualifiedName(*(CXE->getMethodDecl()));
         os << "' with args '";
         for ( unsigned I=0, E=CE->getNumArgs(); I != E; ++I) {
              if (I) os <<", ";
              CE->getArg(I)->printPretty(os,0,Policy);
         }
         os << "' with implicit object '";
         const Expr * E = IOA->IgnoreParenNoopCasts(C.getASTContext());
         QualType QE = E->getType().getCanonicalType();
         os << QE.getAsString()<<" ";
         switch( E->getStmtClass() ) {
             case Stmt::MemberExprClass:
                 os << dyn_cast<MemberExpr>(E)->getMemberDecl()->getQualifiedNameAsString();
                 break;
             case Stmt::DeclRefExprClass:
                 os << dyn_cast<DeclRefExpr>(E)->getDecl()->getQualifiedNameAsString();
                 break;
             case Stmt::CXXOperatorCallExprClass:  
                 dyn_cast<CXXOperatorCallExpr>(E)->printPretty(os,0,Policy);
                 break;
             case Stmt::CXXBindTemporaryExprClass:
                 dyn_cast<CXXBindTemporaryExpr>(E)->printPretty(os,0,Policy);
                 break;
             case Stmt::CXXMemberCallExprClass:
                 dyn_cast<CXXMemberCallExpr>(E)->printPretty(os,0,Policy);
                 break;
             case Stmt::UnaryOperatorClass:
                 dyn_cast<UnaryOperator>(E)->printPretty(os,0,Policy);
                 break;
             default:
                 E->printPretty(os,0,Policy);
                 os << " unhandled expr class " <<E->getStmtClassName();
             }
         os<<"'\n";

         support::writeLog(os.str(),tname);
  }
  return ;
}