clang 23.0.0git
PointerFlowAnalysis.cpp
Go to the documentation of this file.
1//===- PointerFlowAnalysis.cpp - WPA for PointerFlow ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "SSAFAnalysesCommon.h"
18#include "llvm/ADT/STLFunctionalExtras.h"
19#include "llvm/ADT/iterator_range.h"
20#include "llvm/Support/Error.h"
21#include "llvm/Support/JSON.h"
22#include <memory>
23
24using namespace clang::ssaf;
25using namespace llvm;
26
27namespace {
28
29//===----------------------------------------------------------------------===//
30// PointerFlowAnalysis---converts PointerFlowEntitySummary(s) in an LUSummary to
31// a PointerFlowAnalysisResult
32//===----------------------------------------------------------------------===//
33
34// Serialized as a flat array of alternating [EntityId, EdgesArray, ...] pairs.
35json::Object
36serializePointerFlowAnalysisResult(const PointerFlowAnalysisResult &R,
38 json::Array Content;
39
40 for (const auto &[Id, EntityEdges] : R.Edges) {
41 Content.push_back(IdToJSON(Id));
42 Content.push_back(json::Value(edgeSetToJSON(EntityEdges, IdToJSON)));
43 }
44
45 json::Object Result;
46
47 Result[PointerFlowAnalysisResultName] = std::move(Content);
48 return Result;
49}
50
51Expected<std::unique_ptr<AnalysisResult>> deserializePointerFlowAnalysisResult(
52 const json::Object &Obj, JSONFormat::EntityIdFromJSONFn IdFromJSON) {
53 const json::Array *Content = Obj.getArray(PointerFlowAnalysisResultName);
54
55 if (!Content)
56 return makeSawButExpectedError(Obj, "an object with a key %s",
58
59 if (Content->size() % 2 != 0)
60 return makeSawButExpectedError(*Content,
61 "an even number of elements, got %lu",
62 static_cast<size_t>(Content->size()));
63
64 std::map<EntityId, EdgeSet> Edges;
65
66 for (size_t I = 0; I < Content->size(); I += 2) {
67 const json::Object *IdData = (*Content)[I].getAsObject();
68
69 if (!IdData)
70 return makeSawButExpectedError((*Content)[I],
71 "an object representing EntityId");
72
73 auto Id = IdFromJSON(*IdData);
74
75 if (!Id)
76 return Id.takeError();
77
78 const json::Array *EdgesData = (*Content)[I + 1].getAsArray();
79
80 if (!EdgesData)
81 return makeSawButExpectedError((*Content)[I + 1],
82 "an array of arrays representing EdgeSet");
83
84 auto EntityEdges = edgeSetFromJSON(*EdgesData, IdFromJSON);
85
86 if (!EntityEdges)
87 return EntityEdges.takeError();
88 Edges[*Id] = std::move(*EntityEdges);
89 }
90
91 auto Ret = std::make_unique<PointerFlowAnalysisResult>();
92
93 Ret->Edges = std::move(Edges);
94 return Ret;
95}
96
97JSONFormat::AnalysisResultRegistry::Add<PointerFlowAnalysisResult>
98 RegisterPointerFlowResultForJSON(serializePointerFlowAnalysisResult,
99 deserializePointerFlowAnalysisResult);
100
101class PointerFlowAnalysis final
102 : public SummaryAnalysis<PointerFlowAnalysisResult,
103 PointerFlowEntitySummary> {
104public:
105 llvm::Error add(EntityId Id,
106 const PointerFlowEntitySummary &Summary) override {
107 auto EdgesOfEntity = getEdges(Summary);
108
109 getResult().Edges[Id] = EdgeSet(EdgesOfEntity.begin(), EdgesOfEntity.end());
110 return llvm::Error::success();
111 }
112};
113
115 RegisterPointerFlowAnalysis("Whole-program pointer flow analysis");
116
117} // namespace
118
119// NOLINTNEXTLINE(misc-use-internal-linkage)
Result
Implement __builtin_bit_cast and related operations.
volatile int PointerFlowAnalysisAnchorSource
llvm::function_ref< llvm::Expected< EntityId >(const Object &)> EntityIdFromJSONFn
Definition JSONFormat.h:71
llvm::function_ref< Object(EntityId)> EntityIdToJSONFn
Definition JSONFormat.h:70
Typed intermediate that concrete summary analyses inherit from.
PRESERVE_NONE bool Ret(InterpState &S, CodePtr &PC)
Definition Interp.h:258
llvm::json::Array edgeSetToJSON(llvm::iterator_range< EdgeSet::const_iterator > Edges, JSONFormat::EntityIdToJSONFn IdToJSON)
Serialize an EdgeSet {(src1, dest1), (src1, dest2), (src2, dest3), (src2, dest4), ....
std::map< EntityPointerLevel, EntityPointerLevelSet > EdgeSet
Maps each source node to its destination nodes:
Definition PointerFlow.h:23
llvm::Error makeSawButExpectedError(const JSONTy &Saw, llvm::StringRef Expected, const Ts &...ExpectedArgs)
llvm::Expected< EdgeSet > edgeSetFromJSON(const llvm::json::Array &EdgesData, JSONFormat::EntityIdFromJSONFn IdFromJSON)
Deserialize an EdgeSet from the array format produced by edgeSetToJSON.
constexpr llvm::StringLiteral PointerFlowAnalysisResultName
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
Registers AnalysisT with the unified registry.
A PointerFlowAnalysisResult is a set of pointer-flow edges, i.e., a pointer-flow graph.