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