[llvm-branch-commits] [clang] [SSAF][WPA] Add PointerFlowReachableAnalysis (PR #193097)

Ziqing Luo via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Apr 30 16:46:53 PDT 2026


================
@@ -102,14 +109,125 @@ class PointerFlowAnalysis final
                   const PointerFlowEntitySummary &Summary) override {
     auto EdgesOfEntity = getEdges(Summary);
 
-    getResult().Edges[Id] = EdgeSet(EdgesOfEntity.begin(), EdgesOfEntity.end());
+    this->getResult().Edges[Id] =
+        EdgeSet(EdgesOfEntity.begin(), EdgesOfEntity.end());
     return llvm::Error::success();
   }
 };
 
 AnalysisRegistry::Add<PointerFlowAnalysis>
     RegisterPointerFlowAnalysis("Whole-program pointer flow analysis");
 
+//===----------------------------------------------------------------------===//
+// PointerFlowReachableAnalysis---computes reachable node
+//===----------------------------------------------------------------------===//
+
+json::Object serializePointerFlowReachableAnalysisResult(
+    const UnsafeBufferReachableAnalysisResult &R,
+    JSONFormat::EntityIdToJSONFn IdToJSON) {
+  json::Object Result;
+
+  Result[UnsafeBufferReachableAnalysisResultName] =
+      entityPointerLevelMapToJSON(R.Reachables, IdToJSON);
+  return Result;
+}
+
+Expected<std::unique_ptr<AnalysisResult>>
+deserializePointerFlowReachableAnalysisResult(
+    const json::Object &Obj, JSONFormat::EntityIdFromJSONFn IdFromJSON) {
+  const json::Array *Content =
+      Obj.getArray(UnsafeBufferReachableAnalysisResultName);
+
+  if (!Content)
+    return makeSawButExpectedError(
+        Obj, "an object with a key %s",
+        UnsafeBufferReachableAnalysisResultName.data());
+
+  auto Reachables = entityPointerLevelMapFromJSON(*Content, IdFromJSON);
+
+  if (!Reachables)
+    return Reachables.takeError();
+
+  auto Ret = std::make_unique<UnsafeBufferReachableAnalysisResult>();
+
+  Ret->Reachables = std::move(*Reachables);
+  return Ret;
+}
+
+JSONFormat::AnalysisResultRegistry::Add<UnsafeBufferReachableAnalysisResult>
+    RegisterPointerFlowReachableResultForJSON(
+        serializePointerFlowReachableAnalysisResult,
+        deserializePointerFlowReachableAnalysisResult);
+
+/// Computes all the reachable "nodes" (pointers) in a pointer flow graph from a
+/// provided starter node set.  Specifically, the starter set is the unsafe
+/// pointers found by `UnsafeBufferUsageAnalysis`.
+class UnsafeBufferReachableAnalysis
+    : public DerivedAnalysis<UnsafeBufferReachableAnalysisResult,
+                             PointerFlowAnalysisResult,
+                             UnsafeBufferUsageAnalysisResult> {
+  using GraphT = std::map<EntityId, EdgeSet>;
+  const GraphT *Graph = nullptr;
+
+  // Use pointers for efficiency. Both `Graph` and `Reachables` in the result
+  // are tree-based containers that only grow. So pointers to them are stable.
+  using EPLPtr = const EntityPointerLevel *;
+  using EPLPtrSet = std::unordered_set<EPLPtr>;
+  // The analysis needs to track EPLs with their contributor IDs:
+  using EPLPtrSetWithId = std::map<EntityId, std::unordered_set<EPLPtr>>;
----------------
ziqingluo-90 wrote:

Just realized that `EPLPtrSet` and `EPLPtrSetWithId` is no longer in use.  Problem solved I guess.

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


More information about the llvm-branch-commits mailing list