[llvm-branch-commits] [clang] [SSAF][UnsafeBufferUsage] Implement AST visitor that respects the contribution model (PR #188652)
Balázs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Apr 7 13:53:28 PDT 2026
================
@@ -16,148 +16,102 @@
#include "clang/ScalableStaticAnalysisFramework/Core/ASTEntityMapping.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/ExtractorRegistry.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryBuilder.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Error.h"
-#include <memory>
+#include "llvm/Support/ErrorHandling.h"
-namespace {
using namespace clang;
using namespace ssaf;
+namespace {
-static llvm::Error makeCreateEntityNameError(const NamedDecl *FailedDecl,
- ASTContext &Ctx) {
- std::string LocStr = FailedDecl->getSourceRange().getBegin().printToString(
- Ctx.getSourceManager());
- return llvm::createStringError(
- "failed to create entity name for %s declared at %s",
- FailedDecl->getNameAsString().c_str(), LocStr.c_str());
-}
-
-static llvm::Error makeAddEntitySummaryError(const NamedDecl *FailedContributor,
- ASTContext &Ctx) {
- std::string LocStr =
- FailedContributor->getSourceRange().getBegin().printToString(
- Ctx.getSourceManager());
- return llvm::createStringError(
- "failed to add entity summary for contributor %s declared at %s",
- FailedContributor->getNameAsString().c_str(), LocStr.c_str());
-}
+struct UnsafePointerMatcher {
+ std::set<const Expr *> UnsafePointers;
-Expected<EntityPointerLevelSet>
-buildEntityPointerLevels(std::set<const Expr *> &&UnsafePointers,
- UnsafeBufferUsageTUSummaryExtractor &Extractor,
- ASTContext &Ctx,
- std::function<EntityId(EntityName)> AddEntity) {
- EntityPointerLevelSet Result{};
- llvm::Error AllErrors = llvm::ErrorSuccess();
-
- for (const Expr *Ptr : UnsafePointers) {
- Expected<EntityPointerLevelSet> Translation =
- translateEntityPointerLevel(Ptr, Ctx, AddEntity);
-
- if (Translation) {
- // Filter out those temporary invalid EntityPointerLevels associated with
- // `&E` pointers:
- auto FilteredTranslation = llvm::make_filter_range(
- *Translation, [](const EntityPointerLevel &E) -> bool {
- return E.getPointerLevel() > 0;
- });
- Result.insert(FilteredTranslation.begin(), FilteredTranslation.end());
- continue;
- }
- AllErrors = llvm::joinErrors(std::move(AllErrors), Translation.takeError());
+ bool matches(const DynTypedNode &N, ASTContext &Ctx,
+ const NamedDecl *Contributor) {
+ return matchUnsafePointers(N, Ctx, UnsafePointers);
}
- if (AllErrors)
- return AllErrors;
- return Result;
-}
-} // namespace
+};
-static std::set<const Expr *> findUnsafePointersInContributor(const Decl *D) {
- if (isa<FunctionDecl>(D) || isa<VarDecl>(D))
- return findUnsafePointers(D);
- if (auto *RD = dyn_cast<RecordDecl>(D)) {
- std::set<const Expr *> Result;
+void findFactsInContributor(const NamedDecl *Contributor, ASTContext &Ctx,
+ std::set<const Expr *> &UnsafePointers) {
+ UnsafePointerMatcher Matcher;
+ ContributorFactFinder<UnsafePointerMatcher> Finder(Ctx, Matcher);
- for (const FieldDecl *FD : RD->fields()) {
- Result.merge(findUnsafePointers(FD));
- }
- return Result;
- }
- return {};
+ Finder.findMatches(Contributor);
+ UnsafePointers.merge(Matcher.UnsafePointers);
}
+} // namespace
-std::unique_ptr<UnsafeBufferUsageEntitySummary>
-UnsafeBufferUsageTUSummaryExtractor::extractEntitySummary(
- const Decl *Contributor, ASTContext &Ctx, llvm::Error &Error) {
- auto AddEntity = [this](EntityName EN) { return addEntity(EN); };
- Expected<EntityPointerLevelSet> EPLs = buildEntityPointerLevels(
- findUnsafePointersInContributor(Contributor), *this, Ctx, AddEntity);
-
- if (EPLs)
- return std::make_unique<UnsafeBufferUsageEntitySummary>(
- UnsafeBufferUsageEntitySummary(std::move(*EPLs)));
- Error = EPLs.takeError();
- return nullptr;
-}
+class clang::ssaf::UnsafeBufferUsageTUSummaryExtractor
+ : public TUSummaryExtractor {
+public:
+ UnsafeBufferUsageTUSummaryExtractor(TUSummaryBuilder &Builder)
+ : TUSummaryExtractor(Builder) {}
-void UnsafeBufferUsageTUSummaryExtractor::HandleTranslationUnit(
- ASTContext &Ctx) {
+ EntityId addEntity(EntityName EN) { return SummaryBuilder.addEntity(EN); }
- // FIXME: I suppose finding contributor Decls is commonly needed by all/many
- // extractors
- class ContributorFinder : public DynamicRecursiveASTVisitor {
- public:
- std::vector<const NamedDecl *> Contributors;
+ Expected<std::unique_ptr<UnsafeBufferUsageEntitySummary>>
+ extractEntitySummary(const NamedDecl *Contributor, ASTContext &Ctx) {
+ std::set<const Expr *> UnsafePointers;
+ EntityPointerLevelSet Results;
- bool VisitFunctionDecl(FunctionDecl *D) override {
- Contributors.push_back(D);
- return true;
- }
+ findFactsInContributor(Contributor, Ctx, UnsafePointers);
+ for (const Expr *Ptr : UnsafePointers) {
+ Expected<EntityPointerLevelSet> Translation =
+ translateEntityPointerLevel(Ptr, Ctx, [this](const EntityName &EN) {
+ return SummaryBuilder.addEntity(EN);
+ });
- bool VisitRecordDecl(RecordDecl *D) override {
- Contributors.push_back(D);
- return true;
+ if (Translation) {
+ // Filter out those temporary invalid EntityPointerLevels associated
+ // with
+ // `&E` pointers. They need no transformation of entities:
----------------
steakhal wrote:
I have a suspicion that the newline in the middle of this comment was inserted by clang-format at some point. Maybe it fits nicely.
https://github.com/llvm/llvm-project/pull/188652
More information about the llvm-branch-commits
mailing list