File indexing completed on 2023-06-07 22:25:21
0001
0002
0003
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 }