Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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