Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:51

0001 //== StaticLocalChecker.cpp - Checks for non-const static locals --------------*- C++ -*--==//
0002 //
0003 // by Thomas Hauth [ Thomas.Hauth@cern.ch ]
0004 //
0005 //===----------------------------------------------------------------------===//
0006 
0007 #include "StaticLocalChecker.h"
0008 
0009 #include "CmsSupport.h"
0010 #include <iostream>
0011 #include <clang/AST/Attr.h>
0012 using namespace clang;
0013 using namespace ento;
0014 using namespace llvm;
0015 
0016 namespace clangcms {
0017 
0018   void StaticLocalChecker::checkASTDecl(const clang::VarDecl *D,
0019                                         clang::ento::AnalysisManager &Mgr,
0020                                         clang::ento::BugReporter &BR) const {
0021     clang::QualType t = D->getType();
0022     if (D->hasAttr<CMSThreadGuardAttr>() || D->hasAttr<CMSThreadSafeAttr>() || D->hasAttr<CMSSaAllowAttr>())
0023       return;
0024     if (((D->isStaticLocal() || D->isStaticDataMember()) &&
0025          D->getTSCSpec() != clang::ThreadStorageClassSpecifier::TSCS_thread_local) &&
0026         !support::isConst(t)) {
0027       clang::ento::PathDiagnosticLocation DLoc =
0028           clang::ento::PathDiagnosticLocation::createBegin(D, BR.getSourceManager());
0029 
0030       if (!m_exception.reportGlobalStaticForType(t, DLoc, BR))
0031         return;
0032       if (support::isSafeClassName(t.getCanonicalType().getAsString()))
0033         return;
0034 
0035       std::string buf;
0036       llvm::raw_string_ostream os(buf);
0037       os << "Non-const variable '" << t.getAsString() << " " << D->getQualifiedNameAsString()
0038          << "' is static local or static member data and might be thread-unsafe";
0039       if (!BT)
0040         BT = std::make_unique<clang::ento::BugType>(this, "non-const static variable", "ThreadSafety");
0041       std::unique_ptr<clang::ento::BasicBugReport> R =
0042           std::make_unique<clang::ento::BasicBugReport>(*BT, llvm::StringRef(os.str()), DLoc);
0043       R->setDeclWithIssue(D);
0044       R->addRange(D->getSourceRange());
0045       BR.emitReport(std::move(R));
0046       return;
0047     }
0048   }
0049 
0050 }  // namespace clangcms