[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


================
@@ -0,0 +1,148 @@
+//===-- SSAFAnalysesCommon.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  Common code in SSAF analyses implementations
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_SSAFANALYSESCOMMON_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_SSAFANALYSESCOMMON_H
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/JSON.h"
+
+using namespace clang;
+
+template <typename NodeTy, typename... Ts>
+static inline llvm::Error makeErrAtNode(ASTContext &Ctx, const NodeTy &N,
+                                        StringRef Fmt, const Ts &...Args) {
+  std::string LocStr = N.getBeginLoc().printToString(Ctx.getSourceManager());
+  llvm::SmallVector<char> FmtData;
+
+  (Fmt + " at %s").toStringRef(FmtData);
+  return llvm::createStringError(FmtData.data(), Args..., LocStr.c_str());
+}
+
+static inline llvm::Error makeEntityNameErr(ASTContext &Ctx,
+                                            const NamedDecl &D) {
+  return makeErrAtNode(Ctx, D, "failed to create entity name for %s",
+                       D.getNameAsString().data());
+}
+
+static inline llvm::Error makeAddEntitySummaryErr(ASTContext &Ctx,
+                                                  const NamedDecl *D) {
+  std::string LocStr = D->getBeginLoc().printToString(Ctx.getSourceManager());
+
+  return llvm::createStringError("failed to add entity summary for %s at %s",
+                                 D->getNameAsString().data(), LocStr.c_str());
+}
+
+template <typename... Ts>
+static inline llvm::Error makeSawButExpectedError(const llvm::json::Value &Saw,
+                                                  llvm::StringRef Expected,
+                                                  const Ts &...ExpectedArgs) {
+  std::string Fmt = ("saw %s but expected " + Expected).str();
+  std::string SawStr = llvm::formatv("{0:2}", Saw).str();
+
+  return llvm::createStringError(Fmt.c_str(), SawStr.c_str(), ExpectedArgs...);
+}
+
+template <typename DeclOrExpr>
+static inline bool hasPtrOrArrType(const DeclOrExpr &E) {
+  return llvm::isa<PointerType>(E.getType().getCanonicalType()) ||
+         llvm::isa<ArrayType>(E.getType().getCanonicalType());
+}
+
+namespace clang::ssaf {
+/// Traverses the AST and finds contributors:
+class ContributorFinder : public DynamicRecursiveASTVisitor {
+public:
+  std::vector<const NamedDecl *> Contributors;
+
+  bool VisitFunctionDecl(FunctionDecl *D) override {
+    Contributors.push_back(D);
+    return true;
+  }
+
+  bool VisitRecordDecl(RecordDecl *D) override {
+    Contributors.push_back(D);
+    return true;
+  }
+
+  bool VisitVarDecl(VarDecl *D) override {
+    DeclContext *DC = D->getDeclContext();
+
+    if (DC->isFileContext() || DC->isNamespace())
+      Contributors.push_back(D);
+    return true;
+  }
----------------
steakhal wrote:

>From what I can tell, nothing guarantees that any of these are definitions.
We may have extern declared functions, class forward declarations, or variable declarations or even tentative definitions of variables.

My understanding is that `Contributors` must be definitions.

https://github.com/llvm/llvm-project/pull/188652


More information about the llvm-branch-commits mailing list