void TUFWalker::VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
   CXXMethodDecl *MD = CE->getMethodDecl();
   if (!MD)
     return;
   const CXXMethodDecl *PD = llvm::dyn_cast_or_null<CXXMethodDecl>(AC->getDecl());
   if (!PD)
     return;
   std::string mname = support::getQualifiedName(*MD);
   std::string pname = support::getQualifiedName(*PD);
   llvm::SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
   if (support::isKnownThrUnsafeFunc(mname)) {
     os << "Known thread unsafe function " << mname << " is called in function " << pname;
     PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
     BugType *BT = new BugType(Checker, "known thread unsafe function called", "ThreadSafety");
     std::unique_ptr<BugReport> R = llvm::make_unique<BugReport>(*BT, os.str(), CELoc);
     R->setDeclWithIssue(AC->getDecl());
     R->addRange(CE->getSourceRange());
     BR.emitReport(std::move(R));
     std::string tname = "function-checker.txt.unsorted";
     std::string ostring = "function '" + pname + "' known thread unsafe function '" + mname + "'.\n";
     support::writeLog(ostring, tname);
   }
 }
Beispiel #2
0
void gpWalkAST::VisitCXXMemberCallExpr( clang::CXXMemberCallExpr *CE ) {


    const FunctionDecl * FD = CE->getMethodDecl();
    if (!FD) return;

    std::string mname = FD->getQualifiedNameAsString();
    const char *sfile=BR.getSourceManager().getPresumedLoc(CE->getExprLoc()).getFilename();
    std::string sname(sfile);
    if ( ! support::isInterestingLocation(sname) ) return;
    std::string mdname = ND->getQualifiedNameAsString();
    const Expr * IOA = CE->getImplicitObjectArgument();
    std::string tname = "getparam-dumper.txt.unsorted";
    std::string ps = "const class edm::ParameterSet ";
    std::string ups = "const class edm::UntrackedParameterSet ";
    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);
         const NamedDecl * nd = llvm::dyn_cast<NamedDecl>(AC->getDecl());
         if ( FunctionDecl::classof(ND) ) {
             os << "function decl '" << nd->getQualifiedNameAsString() ;
             os << "' this '"<<mdname;
         } else {
             os << "constructor decl '" << nd->getQualifiedNameAsString() ;
             os << "' initializer for member decl '"<<mdname;
         }
         clang::LangOptions LangOpts;
         LangOpts.CPlusPlus = true;
         clang::PrintingPolicy Policy(LangOpts);
         os << "' with call args '";
         for ( unsigned I=0, E=CE->getNumArgs(); I != E; ++I) {
              if (I) os <<", ";
              os << CE->getType().getCanonicalType().getAsString()<<" ";
              CE->getArg(I)->printPretty(os,0,Policy);
         }
         os << "' with implicit object '";
         const Expr * E = IOA->IgnoreParenCasts();
         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 ;
}
Beispiel #3
0
  void FWalker::ReportDeclRef(const clang::DeclRefExpr *DRE) {
    const clang::VarDecl *D = llvm::dyn_cast_or_null<clang::VarDecl>(DRE->getDecl());
    if (D && (D->hasAttr<CMSThreadGuardAttr>() || D->hasAttr<CMSThreadSafeAttr>()))
      return;
    if (support::isSafeClassName(D->getCanonicalDecl()->getQualifiedNameAsString()))
      return;

    const char *sfile = BR.getSourceManager().getPresumedLoc(D->getLocation()).getFilename();
    std::string fname(sfile);
    if (!support::isInterestingLocation(fname))
      return;
    clang::QualType t = D->getType();
    if (support::isSafeClassName(t.getCanonicalType().getAsString()))
      return;
    const Decl *PD = AC->getDecl();
    std::string dname = "";
    std::string sdname = "";
    if (const NamedDecl *ND = llvm::dyn_cast_or_null<NamedDecl>(PD)) {
      sdname = support::getQualifiedName(*ND);
      dname = ND->getQualifiedNameAsString();
    }
    clang::ento::PathDiagnosticLocation DLoc;
    if (support::isCmsLocalFile(sfile)) {
      if (D->getLocation().isMacroID())
        DLoc = clang::ento::PathDiagnosticLocation(D->getLocation(), BR.getSourceManager());
      else
        DLoc = clang::ento::PathDiagnosticLocation::createBegin(D, BR.getSourceManager());
    } else
      DLoc = clang::ento::PathDiagnosticLocation::createBegin(DRE, BR.getSourceManager(), AC);

    std::string tname = "function-checker.txt.unsorted";

    std::string vname = support::getQualifiedName(*D);
    std::string svname = D->getNameAsString();
    if (D->getTSCSpec() == clang::ThreadStorageClassSpecifier::TSCS_thread_local)
      return;
    if (D->isStaticLocal() && !clangcms::support::isConst(t)) {
      std::string buf;
      llvm::raw_string_ostream os(buf);
      os << "function '" << dname << "' accesses or modifies non-const static local variable '" << svname << "'.\n";
      //		BR.EmitBasicReport(D, Checker, "non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
      std::string ostring = "function '" + sdname + "' static variable '" + vname + "'.\n";
      support::writeLog(ostring, tname);
      return;
    }

    if (D->isStaticDataMember() && !clangcms::support::isConst(t)) {
      std::string buf;
      llvm::raw_string_ostream os(buf);
      os << "function '" << dname << "' accesses or modifies non-const static member data variable '" << svname
         << "'.\n";
      //		BR.EmitBasicReport(D, Checker, "non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
      std::string ostring = "function '" + sdname + "' static variable '" + vname + "'.\n";
      support::writeLog(ostring, tname);
      return;
    }

    if (D->hasGlobalStorage() && !D->isStaticDataMember() && !D->isStaticLocal() && !clangcms::support::isConst(t)) {
      std::string buf;
      llvm::raw_string_ostream os(buf);
      os << "function '" << dname << "' accesses or modifies non-const global static variable '" << svname << "'.\n";
      //		BR.EmitBasicReport(D, Checker, "non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
      std::string ostring = "function '" + sdname + "' static variable '" + vname + "'.\n";
      support::writeLog(ostring, tname);
      return;
    }
  }
Beispiel #4
0
 const clang::Stmt *ParentStmt(const Stmt *S) {
   const Stmt *P = AC->getParentMap().getParentIgnoreParens(S);
   if (!P)
     return nullptr;
   return P;
 }
Beispiel #5
0
  void Walker::VisitCXXMemberCallExpr(CXXMemberCallExpr *CE) {
    LangOptions LangOpts;
    LangOpts.CPlusPlus = true;
    PrintingPolicy Policy(LangOpts);
    const Decl *D = AC->getDecl();
    std::string dname = "";
    if (const NamedDecl *ND = llvm::dyn_cast_or_null<NamedDecl>(D))
      dname = ND->getQualifiedNameAsString();
    CXXMethodDecl *MD = CE->getMethodDecl();
    if (!MD)
      return;
    std::string mname = MD->getQualifiedNameAsString();
    //	llvm::errs()<<"Parent Decl: '"<<dname<<"'\n";
    //	llvm::errs()<<"Method Decl: '"<<mname<<"'\n";
    //	llvm::errs()<<"call expression '";
    //	CE->printPretty(llvm::errs(),0,Policy);
    //	llvm::errs()<<"'\n";
    //	if (!MD) return;
    llvm::SmallString<100> buf;
    llvm::raw_svector_ostream os(buf);
    if (mname == "edm::Event::getByLabel" || mname == "edm::Event::getManyByType") {
      //			if (const CXXRecordDecl * RD = llvm::dyn_cast_or_null<CXXMethodDecl>(D)->getParent() ) {
      //				llvm::errs()<<"class "<<RD->getQualifiedNameAsString()<<"\n";
      //				llvm::errs()<<"\n";
      //				}
      os << "function '";
      llvm::dyn_cast<CXXMethodDecl>(D)->getNameForDiagnostic(os, Policy, true);
      os << "' ";
      //			os<<"call expression '";
      //			CE->printPretty(os,0,Policy);
      //			os<<"' ";
      if (mname == "edm::Event::getByLabel") {
        os << "calls edm::Event::getByLabel with arguments '";
        QualType QT;
        for (auto I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
          QT = (*I)->getType();
          std::string qtname = QT.getCanonicalType().getAsString();
          if (qtname.substr(0, 17) == "class edm::Handle") {
            //					os<<"argument name '";
            //					(*I)->printPretty(os,0,Policy);
            //					os<<"' ";
            const CXXRecordDecl *RD = QT->getAsCXXRecordDecl();
            std::string rname = RD->getQualifiedNameAsString();
            os << rname << " ";
            const ClassTemplateSpecializationDecl *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD);
            for (unsigned J = 0, F = SD->getTemplateArgs().size(); J != F; ++J) {
              SD->getTemplateArgs().data()[J].print(Policy, os);
              os << ", ";
            }
          } else {
            os << " " << qtname << " ";
            (*I)->printPretty(os, nullptr, Policy);
            os << ", ";
          }
        }
        os << "'\n";
      } else {
        os << "calls edm::Event::getManyByType with argument '";
        QualType QT = (*CE->arg_begin())->getType();
        const CXXRecordDecl *RD = QT->getAsCXXRecordDecl();
        os << "getManyByType , ";
        const ClassTemplateSpecializationDecl *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD);
        const TemplateArgument TA = SD->getTemplateArgs().data()[0];
        const QualType AQT = TA.getAsType();
        const CXXRecordDecl *SRD = AQT->getAsCXXRecordDecl();
        os << SRD->getQualifiedNameAsString() << " ";
        const ClassTemplateSpecializationDecl *SVD = dyn_cast<ClassTemplateSpecializationDecl>(SRD);
        for (unsigned J = 0, F = SVD->getTemplateArgs().size(); J != F; ++J) {
          SVD->getTemplateArgs().data()[J].print(Policy, os);
          os << ", ";
        }
      }

      //			llvm::errs()<<os.str()<<"\n";
      PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
      BugType *BT = new BugType(Checker, "edm::getByLabel or edm::getManyByType called", "optional");
      std::unique_ptr<BugReport> R = llvm::make_unique<BugReport>(*BT, os.str(), CELoc);
      R->addRange(CE->getSourceRange());
      BR.emitReport(std::move(R));
    } else {
      for (auto I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I) {
        QualType QT = (*I)->getType();
        std::string qtname = QT.getAsString();
        //			if (qtname.find(" edm::Event") != std::string::npos ) llvm::errs()<<"arg type '" << qtname <<"'\n";
        if (qtname == "edm::Event" || qtname == "const edm::Event" || qtname == "edm::Event *" ||
            qtname == "const edm::Event *") {
          std::string tname;
          os << "function '" << dname << "' ";
          os << "calls '";
          MD->getNameForDiagnostic(os, Policy, true);
          os << "' with argument of type '" << qtname << "'\n";
          //				llvm::errs()<<"\n";
          //				llvm::errs()<<"call expression passed edm::Event ";
          //				CE->printPretty(llvm::errs(),0,Policy);
          //				llvm::errs()<<" argument name ";
          //				(*I)->printPretty(llvm::errs(),0,Policy);
          //				llvm::errs()<<" "<<qtname<<"\n";
          PathDiagnosticLocation CELoc = PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
          BugType *BT = new BugType(Checker, "function call with argument of type edm::Event", "optional");
          std::unique_ptr<BugReport> R = llvm::make_unique<BugReport>(*BT, os.str(), CELoc);
          R->addRange(CE->getSourceRange());
          BR.emitReport(std::move(R));
        }
      }
    }
  }
Beispiel #6
0
 void ICEVisitor::VisitBinaryOperator(BinaryOperator *BO) {
   const NamedDecl *ACD = dyn_cast_or_null<NamedDecl>(AC->getDecl());
   VisitChildren(BO);
   std::string ename = "EventNumber_t";
   clang::Expr *LHS = BO->getLHS();
   clang::Expr *RHS = BO->getRHS();
   if (!LHS || !RHS)
     return;
   std::string lname = LHS->getType().getAsString();
   std::string rname = RHS->getType().getAsString();
   if (IntegerLiteral::classof(LHS->IgnoreCasts()) || IntegerLiteral::classof(RHS->IgnoreCasts()))
     return;
   if (!(lname == ename || rname == ename))
     return;
   if (lname == ename && rname == ename)
     return;
   clang::QualType OTy;
   clang::QualType TTy;
   if (lname == ename && ImplicitCastExpr::classof(RHS)) {
     ImplicitCastExpr *ICE = dyn_cast_or_null<ImplicitCastExpr>(RHS);
     TTy = BR.getContext().getCanonicalType(LHS->getType());
     OTy = BR.getContext().getCanonicalType(ICE->getSubExprAsWritten()->getType());
   }
   if (rname == ename && ImplicitCastExpr::classof(LHS)) {
     ImplicitCastExpr *ICE = dyn_cast_or_null<ImplicitCastExpr>(LHS);
     TTy = BR.getContext().getCanonicalType(RHS->getType());
     OTy = BR.getContext().getCanonicalType(ICE->getSubExprAsWritten()->getType());
   }
   if (TTy.isNull() || OTy.isNull())
     return;
   QualType ToTy = TTy.getUnqualifiedType();
   QualType OrigTy = OTy.getUnqualifiedType();
   if (!(ToTy->isIntegerType() || ToTy->isFloatingType()))
     return;
   if (ToTy->isBooleanType())
     return;
   CharUnits size_otype = BR.getContext().getTypeSizeInChars(OrigTy);
   CharUnits size_ttype = BR.getContext().getTypeSizeInChars(ToTy);
   std::string oname = OrigTy.getAsString();
   std::string tname = ToTy.getAsString();
   if (ToTy->isFloatingType()) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << " . " << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(BO, BR.getSourceManager(), AC);
     BR.EmitBasicReport(ACD,
                        CheckName(),
                        "implicit cast of int type to float type",
                        "CMS code rules",
                        os.str(),
                        CELoc,
                        BO->getSourceRange());
   }
   if ((size_otype > size_ttype)) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Cast may result in truncation. "
        << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(BO, BR.getSourceManager(), AC);
     BR.EmitBasicReport(ACD,
                        CheckName(),
                        "implicit cast of int type to smaller int type could truncate",
                        "CMS code rules",
                        os.str(),
                        CELoc,
                        BO->getSourceRange());
   }
   if ((size_otype == size_ttype) &&
       (ToTy->hasSignedIntegerRepresentation() && OrigTy->hasUnsignedIntegerRepresentation() ||
        ToTy->hasUnsignedIntegerRepresentation() && OrigTy->hasSignedIntegerRepresentation())) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Changes int sign type. "
        << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(BO, BR.getSourceManager(), AC);
     BR.EmitBasicReport(
         ACD, CheckName(), "implicit cast ins sign type", "CMS code rules", os.str(), CELoc, BO->getSourceRange());
   }
   return;
   return;
 }
Beispiel #7
0
 void ICEVisitor::VisitImplicitCastExpr(ImplicitCastExpr *CE) {
   const NamedDecl *ACD = dyn_cast<NamedDecl>(AC->getDecl());
   VisitChildren(CE);
   const Expr *SE = CE->getSubExprAsWritten();
   std::string sename = SE->getType().getAsString();
   const clang::Expr *E = CE->getSubExpr();
   if (!(sename == "EventNumber_t"))
     return;
   QualType OTy = BR.getContext().getCanonicalType(E->getType());
   QualType TTy = BR.getContext().getCanonicalType(CE->getType());
   QualType ToTy = TTy.getUnqualifiedType();
   QualType OrigTy = OTy.getUnqualifiedType();
   if (!(ToTy->isIntegerType() || ToTy->isFloatingType()))
     return;
   if (ToTy->isBooleanType())
     return;
   CharUnits size_otype = BR.getContext().getTypeSizeInChars(OrigTy);
   CharUnits size_ttype = BR.getContext().getTypeSizeInChars(ToTy);
   std::string oname = OrigTy.getAsString();
   std::string tname = ToTy.getAsString();
   if (ToTy->isFloatingType()) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << " . " << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
     BR.EmitBasicReport(ACD,
                        CheckName(),
                        "implicit cast of int type to float type",
                        "CMS code rules",
                        os.str(),
                        CELoc,
                        CE->getSourceRange());
   }
   if ((size_otype > size_ttype)) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Cast may result in truncation. "
        << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
     BR.EmitBasicReport(ACD,
                        CheckName(),
                        "implicit cast of int type to smaller int type could truncate",
                        "CMS code rules",
                        os.str(),
                        CELoc,
                        CE->getSourceRange());
   }
   if (ToTy->hasSignedIntegerRepresentation() && OrigTy->hasUnsignedIntegerRepresentation() ||
       ToTy->hasUnsignedIntegerRepresentation() && OrigTy->hasSignedIntegerRepresentation()) {
     llvm::SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
     os << "Cast-to type, " << tname << ". Cast-from type, " << oname << ". Changes int sign type. "
        << support::getQualifiedName(*(ACD));
     clang::ento::PathDiagnosticLocation CELoc =
         clang::ento::PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
     BR.EmitBasicReport(ACD,
                        CheckName(),
                        "implicit cast changes int sign type",
                        "CMS code rules",
                        os.str(),
                        CELoc,
                        CE->getSourceRange());
   }
   return;
 }
Beispiel #8
0
void FWalker::ReportDeclRef ( const clang::DeclRefExpr * DRE) {
  

  if (const clang::VarDecl * D = llvm::dyn_cast<clang::VarDecl>(DRE->getDecl())) {
	if ( D->hasAttr<CMSThreadGuardAttr>() || D->hasAttr<CMSThreadSafeAttr>()) return;
	if ( support::isSafeClassName( D->getCanonicalDecl()->getQualifiedNameAsString() ) ) return;

 	const char *sfile=BR.getSourceManager().getPresumedLoc(D->getLocation()).getFilename();
	std::string fname(sfile);
	if ( fname.find("stdio.h") != std::string::npos 
		|| fname.find("iostream") != std::string::npos 
		|| fname.find("placeholders.hpp") != std::string::npos) return;	

	clang::QualType t =  D->getType();  
	const Decl * PD = AC->getDecl();
	std::string dname =""; 
	std::string sdname =""; 
	if (const NamedDecl * ND = llvm::dyn_cast<NamedDecl>(PD)) {
		sdname = support::getQualifiedName(*ND);
		dname = ND->getQualifiedNameAsString();
	}
	clang::ento::PathDiagnosticLocation DLoc;
	if (support::isCmsLocalFile(sfile)) {
		if (D->getLocation().isMacroID()) 
			DLoc = clang::ento::PathDiagnosticLocation(D->getLocation(),BR.getSourceManager());
		else 
			DLoc = clang::ento::PathDiagnosticLocation::createBegin(D, BR.getSourceManager());
	} else 
		DLoc = clang::ento::PathDiagnosticLocation::createBegin(DRE, BR.getSourceManager(), AC);

	const char * pPath = std::getenv("LOCALRT");
	std::string tname = ""; 
	if ( pPath != NULL ) tname += std::string(pPath);
	tname+="/tmp/function-checker.txt.unsorted";

	std::string vname = support::getQualifiedName(*D);
	std::string svname = D->getNameAsString();

	if ( (D->isStaticLocal() && D->getTSCSpec() != clang::ThreadStorageClassSpecifier::TSCS_thread_local ) && ! clangcms::support::isConst( t ) )
	{
	    if ( support::isSafeClassName( t.getAsString() ) ) return;
		std::string buf;
	    	llvm::raw_string_ostream os(buf);
		os << "function '"<<dname << "' accesses or modifies non-const static local variable '" << svname<< "'.\n";
		BR.EmitBasicReport(D, "FunctionChecker : non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
		std::string ostring =  "function '"+ sdname + "' static variable '" + vname + "'.\n";
		std::ofstream file(tname.c_str(),std::ios::app);
		file<<ostring;
		return;
	}

	if ( (D->isStaticDataMember() && D->getTSCSpec() != clang::ThreadStorageClassSpecifier::TSCS_thread_local ) && ! clangcms::support::isConst( t ) )
	{
	    	std::string buf;
	    	llvm::raw_string_ostream os(buf);
		os << "function '"<<dname<< "' accesses or modifies non-const static member data variable '" << svname << "'.\n";
		BR.EmitBasicReport(D, "FunctionChecker : non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
		std::string ostring =  "function '" + sdname + "' static variable '" + vname + "'.\n";
		std::ofstream file(tname.c_str(),std::ios::app);
		file<<ostring;
	    return;
	}

	
	if ( D->hasGlobalStorage() &&
			  !D->isStaticDataMember() &&
			  !D->isStaticLocal() &&
			  !clangcms::support::isConst( t ) )
	{
	    	std::string buf;
	    	llvm::raw_string_ostream os(buf);
		os << "function '"<<dname << "' accesses or modifies non-const global static variable '" << svname << "'.\n";
		BR.EmitBasicReport(D, "FunctionChecker : non-const static local variable accessed or modified","ThreadSafety",os.str(), DLoc);
		std::string ostring =  "function '" + sdname + "' static variable '" + vname + "'.\n";
		std::ofstream file(tname.c_str(),std::ios::app);
		file<<ostring;
	    return;
	
	}

  }


}