Skip to content

[SSAF][WPA] Add no-op PointerFlow and UnsafeBufferUsage analysis#193089

Open
ziqingluo-90 wants to merge 5 commits intousers/ziqingluo/PR-172429193-3from
users/ziqingluo/PR-174874942-1
Open

[SSAF][WPA] Add no-op PointerFlow and UnsafeBufferUsage analysis#193089
ziqingluo-90 wants to merge 5 commits intousers/ziqingluo/PR-172429193-3from
users/ziqingluo/PR-174874942-1

Conversation

@ziqingluo-90
Copy link
Copy Markdown
Contributor

We need no-op PointerFlow and UnsafeBufferUsage analyses for the
analysis that depends on their summary data.

Refactored PointerFlow and UnsafeBufferUsage serialization for code
sharing.

rdar://174874942

This should fix the bot failure:

    FAILED: clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp:61:5: error: qualified name does not name a class before ‘:’ token
       61 |     : ConstStmtVisitor<EntityPointerLevelTranslator,
          |     ^
…gluo/PR-174874942

 Conflicts:
	clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
	clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
	clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h
	clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt
	clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp
	clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp
	clang/unittests/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp
We need no-op PointerFlow and UnsafeBufferUsage analyses for the
analysis that depends on their summary data.

Refactored PointerFlow and UnsafeBufferUsage serialization for code
sharing.

rdar://174874942
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer clang:analysis clang:ssaf Scalable Static Analysis Framework labels Apr 20, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 20, 2026

@llvm/pr-subscribers-clang-static-analyzer-1
@llvm/pr-subscribers-clang-analysis

@llvm/pr-subscribers-clang

Author: Ziqing Luo (ziqingluo-90)

Changes

We need no-op PointerFlow and UnsafeBufferUsage analyses for the
analysis that depends on their summary data.

Refactored PointerFlow and UnsafeBufferUsage serialization for code
sharing.

rdar://174874942


Patch is 160.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/193089.diff

45 Files Affected:

  • (modified) clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h (+4-8)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h (+36-12)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h (+34)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h (+53)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h (+40)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h (+35)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h (+2-6)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h (+40)
  • (removed) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h (-35)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h (+29)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+66-57)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt (+5)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp (+127-43)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp (+132)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp (+116)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowExtractor.cpp (+329)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp (+129)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.h (+62)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp (+10-29)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp (+121)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp (+59-115)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-bad-array.json (+88)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-bad-summary.json (+65)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-no-key.json (+94)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary.json (+94)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-bad-edges.json (+30)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-bad-id.json (+14)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-empty.json (+11)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-no-key.json (+11)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-odd-count.json (+29)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result.json (+128)
  • (added) clang/test/Analysis/Scalable/PointerFlow/tu-summary-serialization.test (+24)
  • (added) clang/test/Analysis/Scalable/PointerFlow/wpa-result-serialization.test (+32)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-bad-epls.json (+30)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-bad-id.json (+14)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-empty.json (+11)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-no-key.json (+11)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-odd-count.json (+29)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result.json (+86)
  • (modified) clang/test/Analysis/Scalable/UnsafeBufferUsage/tu-summary-serialization.test (+4-5)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/wpa-result-serialization.test (+32)
  • (modified) clang/test/Analysis/Scalable/ssaf-format/list.test (+1)
  • (added) clang/unittests/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowTest.cpp (+1109)
  • (modified) clang/unittests/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp (+185-130)
  • (modified) clang/unittests/ScalableStaticAnalysisFramework/CMakeLists.txt (+1)
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index e0d583c735e61..65b79cfc1c2ff 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -201,14 +201,10 @@ bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
                  const SourceManager &SM);
 } // namespace internal
 
-/// Find unsafe pointers in body/initializer of `D`, if `D` is one of the
-/// followings:
-///   VarDecl
-///   FieldDecl
-///   FunctionDecl
-///   BlockDecl
-///   ObjCMethodDecl
-std::set<const Expr *> findUnsafePointers(const Decl *D);
+/// \return true iff `N` is an unsafe buffer usage and populates the unsafe
+/// pointers in `UnsafePointers`
+bool matchUnsafePointers(const DynTypedNode &N, ASTContext &Ctx,
+                         std::set<const Expr *> &UnsafePointers);
 } // end namespace clang
 
 #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
index 52caa52e1120d..429bb74fb417e 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
@@ -12,17 +12,19 @@
 #include "clang/AST/Expr.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
 #include <set>
 
 namespace clang::ssaf {
 
-/// An EntityPointerLevel represents a level of the declared pointer/array
-/// type of an entity.  In the fully-expanded spelling of the declared type, a
-/// EntityPointerLevel is associated with a '*' (or a '[]`) in that declaration.
+/// An EntityPointerLevel is associated with a level of the declared
+/// pointer/array type of an entity.  In the fully-expanded spelling of the
+/// declared type, a EntityPointerLevel is associated with a '*' (or a '[]`) in
+/// that declaration.
 ///
-/// For example, for 'int *p[10];', there are two EntityPointerLevels. One
-/// is associated with 'int *[10]' of 'p' and the other is associated with 'int
-/// *' of 'p'.
+/// For example, for 'int *p[10];', there are two EntityPointerLevels.
+/// One is associated with 'int *[10]' of 'p' and the other is associated with
+/// 'int *' of 'p'.
 ///
 /// An EntityPointerLevel can be identified by an EntityId and an unsigned
 /// integer indicating the pointer level: '(EntityId, PointerLevel)'.
@@ -32,16 +34,17 @@ namespace clang::ssaf {
 /// For the same example 'int *p[10];', the EntityPointerLevels below are valid:
 /// - '(p, 2)' is associated with the 'int *' part of the declared type of 'p';
 /// - '(p, 1)' is associated with the 'int *[10]' part of the declared type of
-/// 'p'.
+///   'p'.
 class EntityPointerLevel {
   EntityId Entity;
   unsigned PointerLevel;
 
   friend class EntityPointerLevelTranslator;
+  // For unittests:
   friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
 
-  EntityPointerLevel(EntityId Entity, unsigned PointerLevel)
-      : Entity(Entity), PointerLevel(PointerLevel) {}
+  EntityPointerLevel(std::pair<EntityId, unsigned> Pair)
+      : Entity(Pair.first), PointerLevel(Pair.second) {}
 
 public:
   EntityId getEntity() const { return Entity; }
@@ -90,10 +93,31 @@ using EntityPointerLevelSet =
 /// \param Ctx the AST context of `E`
 /// \param AddEntity the callback provided by the caller to convert EntityNames
 /// to EntityIds.
-llvm::Expected<EntityPointerLevelSet>
-translateEntityPointerLevel(const Expr *E, ASTContext &Ctx,
-                            std::function<EntityId(EntityName EN)> AddEntity);
+llvm::Expected<EntityPointerLevelSet> translateEntityPointerLevel(
+    const Expr *E, ASTContext &Ctx,
+    llvm::function_ref<EntityId(EntityName EN)> AddEntity);
 
+/// Creates a `EntityPointerLevel` from a pair of an EntityId and a pointer
+/// level:
 EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
+
+/// Create an EntityPointerLevel (EPL) from a NamedDecl of a pointer/array type.
+///
+/// \param ND the NamedDecl of a pointer/array type.
+/// \param AddEntity the callback provided by the caller to convert EntityNames
+/// to EntityIds.
+/// \param IsFunRet true iff the created EPL is associated with the return type
+/// of a function entity.
+llvm::Expected<EntityPointerLevel>
+createEntityPointerLevel(const NamedDecl *ND,
+                         llvm::function_ref<EntityId(EntityName EN)> AddEntity,
+                         bool IsFunRet = false);
+
+/// Creates a new EntityPointerLevel (EPL) from `E` by incrementing `E`'s
+/// pointer level.
+/// \return the EPL that is associated with the pointee (or array element) type
+/// of `E`'s associated pointer/array type of the same entity.
+EntityPointerLevel incrementPointerLevel(const EntityPointerLevel &E);
 } // namespace clang::ssaf
+
 #endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h
new file mode 100644
index 0000000000000..13ecd880001e6
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h
@@ -0,0 +1,34 @@
+//===- EntityPointerLevelFormat.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
+#include "llvm/ADT/iterator_range.h"
+
+namespace clang::ssaf {
+llvm::json::Value
+entityPointerLevelToJSON(const EntityPointerLevel &EPL,
+                         JSONFormat::EntityIdToJSONFn EntityId2JSON);
+
+Expected<EntityPointerLevel>
+entityPointerLevelFromJSON(const llvm::json::Value &EPLData,
+                           JSONFormat::EntityIdFromJSONFn EntityIdFromJSON);
+
+llvm::json::Array entityPointerLevelSetToJSON(
+    llvm::iterator_range<EntityPointerLevelSet::const_iterator> EPLs,
+    JSONFormat::EntityIdToJSONFn EntityId2JSON);
+
+Expected<EntityPointerLevelSet>
+entityPointerLevelSetFromJSON(const llvm::json::Array &EPLsData,
+                              JSONFormat::EntityIdFromJSONFn EntityIdFromJSON);
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h
new file mode 100644
index 0000000000000..86c976c48a2e3
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h
@@ -0,0 +1,53 @@
+//===- PointerFlow.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
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines an analysis that builds directed graphs where nodes
+//  are pointers and edges are assignment operations, each of which bridges two
+//  nodes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
+
+namespace clang::ssaf {
+
+/// Maps LHSs to their RHS sets:
+using EdgeSet = std::map<EntityPointerLevel, EntityPointerLevelSet>;
+
+class PointerFlowEntitySummary final : public EntitySummary {
+  EdgeSet Edges;
+
+  friend class PointerFlowTUSummaryExtractor;
+  friend PointerFlowEntitySummary buildPointerFlowEntitySummary(EdgeSet Edges);
+  friend llvm::iterator_range<EdgeSet::const_iterator>
+  getEdges(const PointerFlowEntitySummary &);
+
+  PointerFlowEntitySummary(EdgeSet Edges)
+      : EntitySummary(), Edges(std::move(Edges)) {}
+
+public:
+  static constexpr llvm::StringLiteral Name = "PointerFlow";
+
+  SummaryName getSummaryName() const override { return summaryName(); };
+
+  bool operator==(const EdgeSet &Other) const { return Edges == Other; }
+
+  bool operator==(const PointerFlowEntitySummary &Other) const {
+    return Edges == Other.Edges;
+  }
+
+  bool empty() const { return Edges.empty(); }
+
+  static SummaryName summaryName() { return SummaryName{Name.str()}; }
+};
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
new file mode 100644
index 0000000000000..85694c779adf4
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
@@ -0,0 +1,40 @@
+//===- PointerFlowAnalysis.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines PointerFlowAnalysisResult, the whole-program analysis result type
+// for PointerFlowAnalysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisResult.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang::ssaf {
+
+inline constexpr llvm::StringLiteral PointerFlowAnalysisResultName =
+    "PointerFlowAnalysisResult";
+
+struct PointerFlowAnalysisResult final : AnalysisResult {
+  static AnalysisName analysisName() {
+    return AnalysisName(PointerFlowAnalysisResultName.str());
+  }
+
+  /// Whole-program map from EntityIds to their EdgeSets.
+  std::map<EntityId, EdgeSet> Edges;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h
new file mode 100644
index 0000000000000..86bf1de4aaea2
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h
@@ -0,0 +1,35 @@
+//===- PointerFlowFormat.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
+//
+//===----------------------------------------------------------------------===//
+//
+// JSON serialization helpers for EdgeSet (PointerFlow edge maps).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
+#include "llvm/ADT/iterator_range.h"
+
+namespace clang::ssaf {
+
+/// Serialize an EdgeSet as an array of arrays of EntityPointerLevels:
+///   [ [lhs, rhs, rhs, ...], [lhs, rhs, rhs, ...], ... ]
+llvm::json::Array
+edgeSetToJSON(llvm::iterator_range<EdgeSet::const_iterator> Edges,
+              JSONFormat::EntityIdToJSONFn IdToJSON);
+
+/// Deserialize an EdgeSet from the array format produced by `edgeSetToJSON`.
+llvm::Expected<EdgeSet>
+edgeSetFromJSON(const llvm::json::Array &EdgesData,
+                JSONFormat::EntityIdFromJSONFn IdFromJSON);
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
index 250bad5b72f75..27bda9f773085 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
@@ -12,14 +12,10 @@
 #include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include <set>
 
 namespace clang::ssaf {
-
-/// An UnsafeBufferUsageEntitySummary is an immutable set of unsafe buffers, in
-/// the form of EntityPointerLevel.
+/// An UnsafeBufferUsageEntitySummary contains a set of EntityPointerLevels
+/// extracted from unsafe buffer pointers contributed by an entity.
 class UnsafeBufferUsageEntitySummary final : public EntitySummary {
   const EntityPointerLevelSet UnsafeBuffers;
 
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
new file mode 100644
index 0000000000000..aba566498b44b
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
@@ -0,0 +1,40 @@
+//===- UnsafeBufferUsageAnalysis.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines UnsafeBufferUsageAnalysisResult, the whole-program analysis result
+// type for UnsafeBufferUsageAnalysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisResult.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang::ssaf {
+
+inline constexpr llvm::StringLiteral UnsafeBufferUsageAnalysisResultName =
+    "UnsafeBufferUsageAnalysisResult";
+
+struct UnsafeBufferUsageAnalysisResult final : AnalysisResult {
+  static AnalysisName analysisName() {
+    return AnalysisName(UnsafeBufferUsageAnalysisResultName.str());
+  }
+
+  /// Whole-program set of unsafe buffer pointers:
+  std::map<EntityId, EntityPointerLevelSet> UnsafeBuffers;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h
deleted file mode 100644
index 13d4e18b4e81f..0000000000000
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- UnsafeBufferUsageExtractor.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
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
-#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
-
-#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryBuilder.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryExtractor.h"
-#include "llvm/Support/Error.h"
-#include <memory>
-
-namespace clang::ssaf {
-class UnsafeBufferUsageTUSummaryExtractor : public TUSummaryExtractor {
-public:
-  UnsafeBufferUsageTUSummaryExtractor(TUSummaryBuilder &Builder)
-      : TUSummaryExtractor(Builder) {}
-
-  EntityId addEntity(EntityName EN) { return SummaryBuilder.addEntity(EN); }
-
-  std::unique_ptr<UnsafeBufferUsageEntitySummary>
-  extractEntitySummary(const Decl *Contributor, ASTContext &Ctx,
-                       llvm::Error &Error);
-
-  void HandleTranslationUnit(ASTContext &Ctx) override;
-};
-} // namespace clang::ssaf
-
-#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
index 2030dc8a12030..26b1fe4a47840 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
@@ -32,10 +32,39 @@ extern volatile int SSAFAnalysisRegistryAnchorSource;
 [[maybe_unused]] static int SSAFAnalysisRegistryAnchorDestination =
     SSAFAnalysisRegistryAnchorSource;
 
+// This anchor is used to force the linker to link the UnsafeBufferUsage
+// JSON format.
 extern volatile int UnsafeBufferUsageSSAFJSONFormatAnchorSource;
 [[maybe_unused]] static int UnsafeBufferUsageSSAFJSONFormatAnchorDestination =
     UnsafeBufferUsageSSAFJSONFormatAnchorSource;
 
+// This anchor is used to force the linker to link the
+// UnsafeBufferUsageTUSummaryExtractor.
+...
[truncated]

@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 20, 2026

@llvm/pr-subscribers-clang-ssaf

Author: Ziqing Luo (ziqingluo-90)

Changes

We need no-op PointerFlow and UnsafeBufferUsage analyses for the
analysis that depends on their summary data.

Refactored PointerFlow and UnsafeBufferUsage serialization for code
sharing.

rdar://174874942


Patch is 160.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/193089.diff

45 Files Affected:

  • (modified) clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h (+4-8)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h (+36-12)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h (+34)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h (+53)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h (+40)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h (+35)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h (+2-6)
  • (added) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h (+40)
  • (removed) clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h (-35)
  • (modified) clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h (+29)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+66-57)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeLists.txt (+5)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp (+127-43)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp (+132)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp (+116)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowExtractor.cpp (+329)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp (+129)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.h (+62)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp (+10-29)
  • (added) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp (+121)
  • (modified) clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp (+59-115)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-bad-array.json (+88)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-bad-summary.json (+65)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary-no-key.json (+94)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/tu-summary.json (+94)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-bad-edges.json (+30)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-bad-id.json (+14)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-empty.json (+11)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-no-key.json (+11)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result-odd-count.json (+29)
  • (added) clang/test/Analysis/Scalable/PointerFlow/Inputs/wpa-result.json (+128)
  • (added) clang/test/Analysis/Scalable/PointerFlow/tu-summary-serialization.test (+24)
  • (added) clang/test/Analysis/Scalable/PointerFlow/wpa-result-serialization.test (+32)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-bad-epls.json (+30)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-bad-id.json (+14)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-empty.json (+11)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-no-key.json (+11)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result-odd-count.json (+29)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/Inputs/wpa-result.json (+86)
  • (modified) clang/test/Analysis/Scalable/UnsafeBufferUsage/tu-summary-serialization.test (+4-5)
  • (added) clang/test/Analysis/Scalable/UnsafeBufferUsage/wpa-result-serialization.test (+32)
  • (modified) clang/test/Analysis/Scalable/ssaf-format/list.test (+1)
  • (added) clang/unittests/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowTest.cpp (+1109)
  • (modified) clang/unittests/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageTest.cpp (+185-130)
  • (modified) clang/unittests/ScalableStaticAnalysisFramework/CMakeLists.txt (+1)
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index e0d583c735e61..65b79cfc1c2ff 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -201,14 +201,10 @@ bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
                  const SourceManager &SM);
 } // namespace internal
 
-/// Find unsafe pointers in body/initializer of `D`, if `D` is one of the
-/// followings:
-///   VarDecl
-///   FieldDecl
-///   FunctionDecl
-///   BlockDecl
-///   ObjCMethodDecl
-std::set<const Expr *> findUnsafePointers(const Decl *D);
+/// \return true iff `N` is an unsafe buffer usage and populates the unsafe
+/// pointers in `UnsafePointers`
+bool matchUnsafePointers(const DynTypedNode &N, ASTContext &Ctx,
+                         std::set<const Expr *> &UnsafePointers);
 } // end namespace clang
 
 #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
index 52caa52e1120d..429bb74fb417e 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h
@@ -12,17 +12,19 @@
 #include "clang/AST/Expr.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
 #include <set>
 
 namespace clang::ssaf {
 
-/// An EntityPointerLevel represents a level of the declared pointer/array
-/// type of an entity.  In the fully-expanded spelling of the declared type, a
-/// EntityPointerLevel is associated with a '*' (or a '[]`) in that declaration.
+/// An EntityPointerLevel is associated with a level of the declared
+/// pointer/array type of an entity.  In the fully-expanded spelling of the
+/// declared type, a EntityPointerLevel is associated with a '*' (or a '[]`) in
+/// that declaration.
 ///
-/// For example, for 'int *p[10];', there are two EntityPointerLevels. One
-/// is associated with 'int *[10]' of 'p' and the other is associated with 'int
-/// *' of 'p'.
+/// For example, for 'int *p[10];', there are two EntityPointerLevels.
+/// One is associated with 'int *[10]' of 'p' and the other is associated with
+/// 'int *' of 'p'.
 ///
 /// An EntityPointerLevel can be identified by an EntityId and an unsigned
 /// integer indicating the pointer level: '(EntityId, PointerLevel)'.
@@ -32,16 +34,17 @@ namespace clang::ssaf {
 /// For the same example 'int *p[10];', the EntityPointerLevels below are valid:
 /// - '(p, 2)' is associated with the 'int *' part of the declared type of 'p';
 /// - '(p, 1)' is associated with the 'int *[10]' part of the declared type of
-/// 'p'.
+///   'p'.
 class EntityPointerLevel {
   EntityId Entity;
   unsigned PointerLevel;
 
   friend class EntityPointerLevelTranslator;
+  // For unittests:
   friend EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
 
-  EntityPointerLevel(EntityId Entity, unsigned PointerLevel)
-      : Entity(Entity), PointerLevel(PointerLevel) {}
+  EntityPointerLevel(std::pair<EntityId, unsigned> Pair)
+      : Entity(Pair.first), PointerLevel(Pair.second) {}
 
 public:
   EntityId getEntity() const { return Entity; }
@@ -90,10 +93,31 @@ using EntityPointerLevelSet =
 /// \param Ctx the AST context of `E`
 /// \param AddEntity the callback provided by the caller to convert EntityNames
 /// to EntityIds.
-llvm::Expected<EntityPointerLevelSet>
-translateEntityPointerLevel(const Expr *E, ASTContext &Ctx,
-                            std::function<EntityId(EntityName EN)> AddEntity);
+llvm::Expected<EntityPointerLevelSet> translateEntityPointerLevel(
+    const Expr *E, ASTContext &Ctx,
+    llvm::function_ref<EntityId(EntityName EN)> AddEntity);
 
+/// Creates a `EntityPointerLevel` from a pair of an EntityId and a pointer
+/// level:
 EntityPointerLevel buildEntityPointerLevel(EntityId, unsigned);
+
+/// Create an EntityPointerLevel (EPL) from a NamedDecl of a pointer/array type.
+///
+/// \param ND the NamedDecl of a pointer/array type.
+/// \param AddEntity the callback provided by the caller to convert EntityNames
+/// to EntityIds.
+/// \param IsFunRet true iff the created EPL is associated with the return type
+/// of a function entity.
+llvm::Expected<EntityPointerLevel>
+createEntityPointerLevel(const NamedDecl *ND,
+                         llvm::function_ref<EntityId(EntityName EN)> AddEntity,
+                         bool IsFunRet = false);
+
+/// Creates a new EntityPointerLevel (EPL) from `E` by incrementing `E`'s
+/// pointer level.
+/// \return the EPL that is associated with the pointee (or array element) type
+/// of `E`'s associated pointer/array type of the same entity.
+EntityPointerLevel incrementPointerLevel(const EntityPointerLevel &E);
 } // namespace clang::ssaf
+
 #endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVEL_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h
new file mode 100644
index 0000000000000..13ecd880001e6
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h
@@ -0,0 +1,34 @@
+//===- EntityPointerLevelFormat.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
+#include "llvm/ADT/iterator_range.h"
+
+namespace clang::ssaf {
+llvm::json::Value
+entityPointerLevelToJSON(const EntityPointerLevel &EPL,
+                         JSONFormat::EntityIdToJSONFn EntityId2JSON);
+
+Expected<EntityPointerLevel>
+entityPointerLevelFromJSON(const llvm::json::Value &EPLData,
+                           JSONFormat::EntityIdFromJSONFn EntityIdFromJSON);
+
+llvm::json::Array entityPointerLevelSetToJSON(
+    llvm::iterator_range<EntityPointerLevelSet::const_iterator> EPLs,
+    JSONFormat::EntityIdToJSONFn EntityId2JSON);
+
+Expected<EntityPointerLevelSet>
+entityPointerLevelSetFromJSON(const llvm::json::Array &EPLsData,
+                              JSONFormat::EntityIdFromJSONFn EntityIdFromJSON);
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_ENTITYPOINTERLEVEL_ENTITYPOINTERLEVELFORMAT_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h
new file mode 100644
index 0000000000000..86c976c48a2e3
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h
@@ -0,0 +1,53 @@
+//===- PointerFlow.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
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines an analysis that builds directed graphs where nodes
+//  are pointers and edges are assignment operations, each of which bridges two
+//  nodes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
+
+namespace clang::ssaf {
+
+/// Maps LHSs to their RHS sets:
+using EdgeSet = std::map<EntityPointerLevel, EntityPointerLevelSet>;
+
+class PointerFlowEntitySummary final : public EntitySummary {
+  EdgeSet Edges;
+
+  friend class PointerFlowTUSummaryExtractor;
+  friend PointerFlowEntitySummary buildPointerFlowEntitySummary(EdgeSet Edges);
+  friend llvm::iterator_range<EdgeSet::const_iterator>
+  getEdges(const PointerFlowEntitySummary &);
+
+  PointerFlowEntitySummary(EdgeSet Edges)
+      : EntitySummary(), Edges(std::move(Edges)) {}
+
+public:
+  static constexpr llvm::StringLiteral Name = "PointerFlow";
+
+  SummaryName getSummaryName() const override { return summaryName(); };
+
+  bool operator==(const EdgeSet &Other) const { return Edges == Other; }
+
+  bool operator==(const PointerFlowEntitySummary &Other) const {
+    return Edges == Other.Edges;
+  }
+
+  bool empty() const { return Edges.empty(); }
+
+  static SummaryName summaryName() { return SummaryName{Name.str()}; }
+};
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOW_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
new file mode 100644
index 0000000000000..85694c779adf4
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
@@ -0,0 +1,40 @@
+//===- PointerFlowAnalysis.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines PointerFlowAnalysisResult, the whole-program analysis result type
+// for PointerFlowAnalysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisResult.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang::ssaf {
+
+inline constexpr llvm::StringLiteral PointerFlowAnalysisResultName =
+    "PointerFlowAnalysisResult";
+
+struct PointerFlowAnalysisResult final : AnalysisResult {
+  static AnalysisName analysisName() {
+    return AnalysisName(PointerFlowAnalysisResultName.str());
+  }
+
+  /// Whole-program map from EntityIds to their EdgeSets.
+  std::map<EntityId, EdgeSet> Edges;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWANALYSIS_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h
new file mode 100644
index 0000000000000..86bf1de4aaea2
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h
@@ -0,0 +1,35 @@
+//===- PointerFlowFormat.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
+//
+//===----------------------------------------------------------------------===//
+//
+// JSON serialization helpers for EdgeSet (PointerFlow edge maps).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
+#include "llvm/ADT/iterator_range.h"
+
+namespace clang::ssaf {
+
+/// Serialize an EdgeSet as an array of arrays of EntityPointerLevels:
+///   [ [lhs, rhs, rhs, ...], [lhs, rhs, rhs, ...], ... ]
+llvm::json::Array
+edgeSetToJSON(llvm::iterator_range<EdgeSet::const_iterator> Edges,
+              JSONFormat::EntityIdToJSONFn IdToJSON);
+
+/// Deserialize an EdgeSet from the array format produced by `edgeSetToJSON`.
+llvm::Expected<EdgeSet>
+edgeSetFromJSON(const llvm::json::Array &EdgesData,
+                JSONFormat::EntityIdFromJSONFn IdFromJSON);
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_POINTERFLOW_POINTERFLOWFORMAT_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
index 250bad5b72f75..27bda9f773085 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h
@@ -12,14 +12,10 @@
 #include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include <set>
 
 namespace clang::ssaf {
-
-/// An UnsafeBufferUsageEntitySummary is an immutable set of unsafe buffers, in
-/// the form of EntityPointerLevel.
+/// An UnsafeBufferUsageEntitySummary contains a set of EntityPointerLevels
+/// extracted from unsafe buffer pointers contributed by an entity.
 class UnsafeBufferUsageEntitySummary final : public EntitySummary {
   const EntityPointerLevelSet UnsafeBuffers;
 
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
new file mode 100644
index 0000000000000..aba566498b44b
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
@@ -0,0 +1,40 @@
+//===- UnsafeBufferUsageAnalysis.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines UnsafeBufferUsageAnalysisResult, the whole-program analysis result
+// type for UnsafeBufferUsageAnalysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisResult.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang::ssaf {
+
+inline constexpr llvm::StringLiteral UnsafeBufferUsageAnalysisResultName =
+    "UnsafeBufferUsageAnalysisResult";
+
+struct UnsafeBufferUsageAnalysisResult final : AnalysisResult {
+  static AnalysisName analysisName() {
+    return AnalysisName(UnsafeBufferUsageAnalysisResultName.str());
+  }
+
+  /// Whole-program set of unsafe buffer pointers:
+  std::map<EntityId, EntityPointerLevelSet> UnsafeBuffers;
+};
+
+} // namespace clang::ssaf
+
+#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEANALYSIS_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h
deleted file mode 100644
index 13d4e18b4e81f..0000000000000
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- UnsafeBufferUsageExtractor.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
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
-#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
-
-#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityName.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryBuilder.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/TUSummaryExtractor.h"
-#include "llvm/Support/Error.h"
-#include <memory>
-
-namespace clang::ssaf {
-class UnsafeBufferUsageTUSummaryExtractor : public TUSummaryExtractor {
-public:
-  UnsafeBufferUsageTUSummaryExtractor(TUSummaryBuilder &Builder)
-      : TUSummaryExtractor(Builder) {}
-
-  EntityId addEntity(EntityName EN) { return SummaryBuilder.addEntity(EN); }
-
-  std::unique_ptr<UnsafeBufferUsageEntitySummary>
-  extractEntitySummary(const Decl *Contributor, ASTContext &Ctx,
-                       llvm::Error &Error);
-
-  void HandleTranslationUnit(ASTContext &Ctx) override;
-};
-} // namespace clang::ssaf
-
-#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_ANALYSES_UNSAFEBUFFERUSAGE_UNSAFEBUFFERUSAGEBUILDER_H
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
index 2030dc8a12030..26b1fe4a47840 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h
@@ -32,10 +32,39 @@ extern volatile int SSAFAnalysisRegistryAnchorSource;
 [[maybe_unused]] static int SSAFAnalysisRegistryAnchorDestination =
     SSAFAnalysisRegistryAnchorSource;
 
+// This anchor is used to force the linker to link the UnsafeBufferUsage
+// JSON format.
 extern volatile int UnsafeBufferUsageSSAFJSONFormatAnchorSource;
 [[maybe_unused]] static int UnsafeBufferUsageSSAFJSONFormatAnchorDestination =
     UnsafeBufferUsageSSAFJSONFormatAnchorSource;
 
+// This anchor is used to force the linker to link the
+// UnsafeBufferUsageTUSummaryExtractor.
+...
[truncated]

@github-actions
Copy link
Copy Markdown

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp,h -- clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp clang/include/clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h clang/include/clang/ScalableStaticAnalysisFramework/SSAFBuiltinForceLinker.h clang/lib/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowExtractor.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.h clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.cpp clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageExtractor.cpp --diff_from_common_commit

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
index 85694c779..c45b4a4fc 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h
@@ -1,4 +1,5 @@
-//===- PointerFlowAnalysis.h -------------------------------------*- C++ -*-===//
+//===- PointerFlowAnalysis.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.
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
index aba566498..0d4422960 100644
--- a/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h
@@ -1,4 +1,5 @@
-//===- UnsafeBufferUsageAnalysis.h --------------------------------*- C++ -*-===//
+//===- UnsafeBufferUsageAnalysis.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.
diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp
index ce45f4167..6b16e9176 100644
--- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp
+++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.cpp
@@ -35,9 +35,8 @@ ssaf::getEdges(const PointerFlowEntitySummary &Sum) {
   return Sum.Edges;
 }
 
-Array ssaf::edgeSetToJSON(
-    llvm::iterator_range<EdgeSet::const_iterator> Edges,
-    JSONFormat::EntityIdToJSONFn EntityId2JSON) {
+Array ssaf::edgeSetToJSON(llvm::iterator_range<EdgeSet::const_iterator> Edges,
+                          JSONFormat::EntityIdToJSONFn EntityId2JSON) {
   Array EdgesData;
 
   for (const auto &[LHS, RHSSet] : Edges) {
diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp
index c6f2f6ddc..2c6912a96 100644
--- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp
+++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.cpp
@@ -11,9 +11,9 @@
 // EdgeSets.
 //===----------------------------------------------------------------------===//
 
+#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h"
 #include "SSAFAnalysesCommon.h"
 #include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlow.h"
-#include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowAnalysis.h"
 #include "clang/ScalableStaticAnalysisFramework/Analyses/PointerFlow/PointerFlowFormat.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisRegistry.h"
@@ -53,9 +53,9 @@ Expected<std::unique_ptr<AnalysisResult>> deserializePointerFlowAnalysisResult(
                                    PointerFlowAnalysisResultName.data());
 
   if (Content->size() % 2 != 0)
-    return makeSawButExpectedError(
-        *Content, "an even number of elements, got %lu",
-        (unsigned long)Content->size());
+    return makeSawButExpectedError(*Content,
+                                   "an even number of elements, got %lu",
+                                   (unsigned long)Content->size());
 
   std::map<EntityId, EdgeSet> Edges;
 
diff --git a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp
index b856074ce..1f367720d 100644
--- a/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp
+++ b/clang/lib/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.cpp
@@ -11,11 +11,11 @@
 // EntityPointerLevelSets
 //===----------------------------------------------------------------------===//
 
+#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h"
 #include "SSAFAnalysesCommon.h"
 #include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevel.h"
 #include "clang/ScalableStaticAnalysisFramework/Analyses/EntityPointerLevel/EntityPointerLevelFormat.h"
 #include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsage.h"
-#include "clang/ScalableStaticAnalysisFramework/Analyses/UnsafeBufferUsage/UnsafeBufferUsageAnalysis.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/AnalysisRegistry.h"
 #include "clang/ScalableStaticAnalysisFramework/Core/WholeProgramAnalysis/SummaryAnalysis.h"
@@ -48,16 +48,17 @@ json::Object serializeUnsafeBufferUsageAnalysisResult(
 Expected<std::unique_ptr<AnalysisResult>>
 deserializeUnsafeBufferUsageAnalysisResult(
     const json::Object &Obj, JSONFormat::EntityIdFromJSONFn IdFromJSON) {
-  const json::Array *Content = Obj.getArray(UnsafeBufferUsageAnalysisResultName);
+  const json::Array *Content =
+      Obj.getArray(UnsafeBufferUsageAnalysisResultName);
 
   if (!Content)
     return makeSawButExpectedError(Obj, "an object with a key %s",
                                    UnsafeBufferUsageAnalysisResultName.data());
 
   if (Content->size() % 2 != 0)
-    return makeSawButExpectedError(
-        *Content, "an even number of elements, got %lu",
-        (unsigned long)Content->size());
+    return makeSawButExpectedError(*Content,
+                                   "an even number of elements, got %lu",
+                                   (unsigned long)Content->size());
 
   std::map<EntityId, EntityPointerLevelSet> UnsafeBuffers;
 

@github-actions
Copy link
Copy Markdown

🪟 Windows x64 Test Results

The build failed before running any tests. Click on a failure below to see the details.

[code=1] tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.obj
FAILED: [code=1] tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.obj
sccache C:\clang\clang-msvc\bin\clang-cl.exe  /nologo -TP -DCLANG_BUILD_STATIC -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_GLIBCXX_ASSERTIONS -D_HAS_EXCEPTIONS=0 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -IC:\_work\llvm-project\llvm-project\build\tools\clang\lib\ScalableStaticAnalysisFramework\Analyses -IC:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses -IC:\_work\llvm-project\llvm-project\clang\include -IC:\_work\llvm-project\llvm-project\build\tools\clang\include -IC:\_work\llvm-project\llvm-project\build\include -IC:\_work\llvm-project\llvm-project\llvm\include /DWIN32 /D_WINDOWS   /Zc:inline /Zc:__cplusplus /Oi /Brepro /bigobj /permissive- -Werror=unguarded-availability-new /W4  -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported /Gw /O2 /Ob2  -std:c++17 -MD -UNDEBUG /EHs-c- /GR- /showIncludes /Fotools\clang\lib\ScalableStaticAnalysisFramework\Analyses\CMakeFiles\obj.clangScalableStaticAnalysisFrameworkAnalyses.dir\SSAFAnalysesCommon.cpp.obj /Fdtools\clang\lib\ScalableStaticAnalysisFramework\Analyses\CMakeFiles\obj.clangScalableStaticAnalysisFrameworkAnalyses.dir\ -c -- C:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses\SSAFAnalysesCommon.cpp
C:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses\SSAFAnalysesCommon.cpp(54,24): error: member access into incomplete type 'LambdaExpr'
54 |     VisitFunctionDecl(L->getCallOperator());
|                        ^
C:\_work\llvm-project\llvm-project\build\tools\clang\include\clang/AST/StmtNodes.inc(360,12): note: forward declaration of 'clang::LambdaExpr'
360 | LAMBDAEXPR(LambdaExpr, Expr)
|            ^
In file included from C:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses\SSAFAnalysesCommon.cpp:9:
In file included from C:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses\SSAFAnalysesCommon.h:15:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/AST/ASTContext.h:18:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/AST/CanonicalType.h:17:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/AST/Type.h:20:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/AST/Decl.h:17:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/AST/APValue.h:16:
In file included from C:\_work\llvm-project\llvm-project\clang\include\clang/Basic/LLVM.h:21:
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(64,53): error: incomplete type 'clang::ObjCMethodDecl' named in nested name specifier
64 |   static inline bool doit(const From &Val) { return To::classof(&Val); }
|                                                     ^~~~
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(110,32): note: in instantiation of member function 'llvm::isa_impl<clang::ObjCMethodDecl, clang::Decl>::doit' requested here
110 |     return isa_impl<To, From>::doit(*Val);
|                                ^
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(137,37): note: in instantiation of member function 'llvm::isa_impl_cl<clang::ObjCMethodDecl, const clang::Decl *>::doit' requested here
137 |     return isa_impl_cl<To, FromTy>::doit(Val);
|                                     ^
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(129,9): note: in instantiation of member function 'llvm::isa_impl_wrap<clang::ObjCMethodDecl, const clang::Decl *, const clang::Decl *>::doit' requested here
129 |         doit(simplify_type<const From>::getSimplifiedValue(Val));
|         ^
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(257,58): note: in instantiation of member function 'llvm::isa_impl_wrap<clang::ObjCMethodDecl, const clang::Decl *const, const clang::Decl *>::doit' requested here
257 |         typename simplify_type<const From>::SimpleType>::doit(f);
|                                                          ^
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(509,28): note: in instantiation of member function 'llvm::CastIsPossible<clang::ObjCMethodDecl, const clang::Decl *>::isPossible' requested here
509 |     return SimplifiedSelf::isPossible(
|                            ^
C:\_work\llvm-project\llvm-project\llvm\include\llvm/Support/Casting.h(548,37): note: in instantiation of member function 'llvm::CastInfo<clang::ObjCMethodDecl, clang::Decl *const>::isPossible' requested here
548 |   return (CastInfo<To, const From>::isPossible(Val) || ...);
|                                     ^
C:\_work\llvm-project\llvm-project\clang\lib\ScalableStaticAnalysisFramework\Analyses\SSAFAnalysesCommon.cpp(92,9): note: in instantiation of function template specialization 'llvm::isa<clang::FunctionDecl, clang::BlockDecl, clang::ObjCMethodDecl, clang::RecordDecl, clang::Decl *>' requested here
92 |         isa<FunctionDecl, BlockDecl, ObjCMethodDecl, RecordDecl>(Node))
|         ^
C:\_work\llvm-project\llvm-project\build\tools\clang\include\clang/AST/DeclNodes.inc(142,1): note: forward declaration of 'clang::ObjCMethodDecl'
142 | OBJCMETHOD(ObjCMethod, NamedDecl)
| ^
C:\_work\llvm-project\llvm-project\build\tools\clang\include\clang/AST/DeclNodes.inc(140,34): note: expanded from macro 'OBJCMETHOD'
140 | #  define OBJCMETHOD(Type, Base) NAMED(Type, Base)
|                                  ^
C:\_work\llvm-project\llvm-project\build\tools\clang\include\clang/AST/DeclNodes.inc(136,29): note: expanded from macro 'NAMED'
136 | #  define NAMED(Type, Base) DECL(Type, Base)
|                             ^
C:\_work\llvm-project\llvm-project\clang\include\clang/AST/ASTFwd.h(20,35): note: expanded from macro 'DECL'
20 | #define DECL(DERIVED, BASE) class DERIVED##Decl;
|                                   ^
<scratch space>(24,1): note: expanded from here
24 | ObjCMethodDecl
| ^
2 errors generated.

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

@github-actions
Copy link
Copy Markdown

🐧 Linux x64 Test Results

The build failed before running any tests. Click on a failure below to see the details.

tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.o
FAILED: tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.o
sccache /opt/llvm/bin/clang++ -DCLANG_EXPORTS -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/lib/ScalableStaticAnalysisFramework/Analyses -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include -I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -Wno-nested-anon-types -O3 -DNDEBUG -std=c++17 -UNDEBUG -fno-exceptions -funwind-tables -fno-rtti -MD -MT tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.o -MF tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.o.d -o tools/clang/lib/ScalableStaticAnalysisFramework/Analyses/CMakeFiles/obj.clangScalableStaticAnalysisFrameworkAnalyses.dir/SSAFAnalysesCommon.cpp.o -c /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp:54:24: error: member access into incomplete type 'LambdaExpr'
54 |     VisitFunctionDecl(L->getCallOperator());
|                        ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/AST/StmtNodes.inc:360:12: note: forward declaration of 'clang::LambdaExpr'
360 | LAMBDAEXPR(LambdaExpr, Expr)
|            ^
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp:9:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.h:15:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/ASTContext.h:18:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/CanonicalType.h:17:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/Type.h:20:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/Decl.h:17:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/APValue.h:16:
In file included from /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/Basic/LLVM.h:21:
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:64:53: error: incomplete type 'clang::ObjCMethodDecl' named in nested name specifier
64 |   static inline bool doit(const From &Val) { return To::classof(&Val); }
|                                                     ^~~~
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:110:32: note: in instantiation of member function 'llvm::isa_impl<clang::ObjCMethodDecl, clang::Decl>::doit' requested here
110 |     return isa_impl<To, From>::doit(*Val);
|                                ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:137:37: note: in instantiation of member function 'llvm::isa_impl_cl<clang::ObjCMethodDecl, const clang::Decl *>::doit' requested here
137 |     return isa_impl_cl<To, FromTy>::doit(Val);
|                                     ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:129:9: note: in instantiation of member function 'llvm::isa_impl_wrap<clang::ObjCMethodDecl, const clang::Decl *, const clang::Decl *>::doit' requested here
129 |         doit(simplify_type<const From>::getSimplifiedValue(Val));
|         ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:257:58: note: in instantiation of member function 'llvm::isa_impl_wrap<clang::ObjCMethodDecl, const clang::Decl *const, const clang::Decl *>::doit' requested here
257 |         typename simplify_type<const From>::SimpleType>::doit(f);
|                                                          ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:509:28: note: in instantiation of member function 'llvm::CastIsPossible<clang::ObjCMethodDecl, const clang::Decl *>::isPossible' requested here
509 |     return SimplifiedSelf::isPossible(
|                            ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include/llvm/Support/Casting.h:548:37: note: in instantiation of member function 'llvm::CastInfo<clang::ObjCMethodDecl, clang::Decl *const>::isPossible' requested here
548 |   return (CastInfo<To, const From>::isPossible(Val) || ...);
|                                     ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/lib/ScalableStaticAnalysisFramework/Analyses/SSAFAnalysesCommon.cpp:92:9: note: in instantiation of function template specialization 'llvm::isa<clang::FunctionDecl, clang::BlockDecl, clang::ObjCMethodDecl, clang::RecordDecl, clang::Decl *>' requested here
92 |         isa<FunctionDecl, BlockDecl, ObjCMethodDecl, RecordDecl>(Node))
|         ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:142:1: note: forward declaration of 'clang::ObjCMethodDecl'
142 | OBJCMETHOD(ObjCMethod, NamedDecl)
| ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:140:34: note: expanded from macro 'OBJCMETHOD'
140 | #  define OBJCMETHOD(Type, Base) NAMED(Type, Base)
|                                  ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include/clang/AST/DeclNodes.inc:136:29: note: expanded from macro 'NAMED'
136 | #  define NAMED(Type, Base) DECL(Type, Base)
|                             ^
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include/clang/AST/ASTFwd.h:20:35: note: expanded from macro 'DECL'
20 | #define DECL(DERIVED, BASE) class DERIVED##Decl;
|                                   ^
<scratch space>:24:1: note: expanded from here
24 | ObjCMethodDecl
| ^
2 errors generated.

If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the infrastructure label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:analysis clang:ssaf Scalable Static Analysis Framework clang:static analyzer clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants