Skip to content

Commit e1ff500

Browse files
committed
Merge branch 'development' into f-FilteredAliasSet
2 parents da93441 + 64a7233 commit e1ff500

File tree

131 files changed

+9501
-1155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+9501
-1155
lines changed

config/glibc_function_list_v1-04.05.17.conf

Lines changed: 82 additions & 82 deletions
Large diffs are not rendered by default.

include/phasar/ControlFlow/CFGBase.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ template <typename Derived> class CFGBase {
131131
void print(ByConstRef<f_t> Fun, llvm::raw_ostream &OS) const {
132132
self().printImpl(Fun, OS);
133133
}
134-
[[nodiscard]] nlohmann::json getAsJson(ByConstRef<f_t> Fun) const {
134+
[[nodiscard, deprecated("Please use printAsJson() instead")]] nlohmann::json
135+
getAsJson(ByConstRef<f_t> Fun) const {
135136
return self().getAsJsonImpl(Fun);
136137
}
137138

include/phasar/ControlFlow/CallGraph.h

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
#define PHASAR_CONTROLFLOW_CALLGRAPH_H
1212

1313
#include "phasar/ControlFlow/CallGraphBase.h"
14+
#include "phasar/ControlFlow/CallGraphData.h"
1415
#include "phasar/Utils/ByRef.h"
1516
#include "phasar/Utils/Logger.h"
1617
#include "phasar/Utils/StableVector.h"
1718
#include "phasar/Utils/Utilities.h"
1819

19-
#include "llvm/ADT/ArrayRef.h"
20-
#include "llvm/ADT/DenseMap.h"
21-
#include "llvm/ADT/STLExtras.h"
20+
#include "llvm/IR/Function.h"
2221

2322
#include "nlohmann/json.hpp"
2423

2524
#include <functional>
25+
#include <string>
2626
#include <utility>
2727
#include <vector>
2828

@@ -58,7 +58,7 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
5858
/// Deserializes a previously computed call-graph
5959
template <typename FunctionGetter, typename InstructionGetter>
6060
[[nodiscard]] static CallGraph
61-
deserialize(const nlohmann::json &PrecomputedCG,
61+
deserialize(const CallGraphData &PrecomputedCG,
6262
FunctionGetter GetFunctionFromName,
6363
InstructionGetter GetInstructionFromId);
6464

@@ -86,12 +86,33 @@ class CallGraph : public CallGraphBase<CallGraph<N, F>> {
8686

8787
[[nodiscard]] bool empty() const noexcept { return CallersOf.empty(); }
8888

89+
template <typename FunctionIdGetter, typename InstIdGetter>
90+
void printAsJson(llvm::raw_ostream &OS, FunctionIdGetter GetFunctionId,
91+
InstIdGetter GetInstructionId) const {
92+
CallGraphData CGData;
93+
CGData.FToFunctionVertexTy.reserve(CallersOf.size());
94+
95+
for (const auto &[Fun, Callers] : CallersOf) {
96+
auto &JCallers =
97+
CGData.FToFunctionVertexTy[std::invoke(GetFunctionId, Fun)];
98+
99+
CGData.FToFunctionVertexTy.reserve(Callers->size());
100+
for (const auto &CS : *Callers) {
101+
JCallers.push_back(std::invoke(GetInstructionId, CS));
102+
}
103+
}
104+
105+
CGData.printAsJson(OS);
106+
}
107+
89108
/// Creates a JSON representation of this call-graph suitable for presistent
90109
/// storage.
91110
/// Use the ctor taking a json object for deserialization
92111
template <typename FunctionIdGetter, typename InstIdGetter>
93-
[[nodiscard]] nlohmann::json getAsJson(FunctionIdGetter GetFunctionId,
94-
InstIdGetter GetInstructionId) const {
112+
[[nodiscard]] [[deprecated(
113+
"Please use printAsJson() instead")]] nlohmann::json
114+
getAsJson(FunctionIdGetter GetFunctionId,
115+
InstIdGetter GetInstructionId) const {
95116
nlohmann::json J;
96117

97118
for (const auto &[Fun, Callers] : CallersOf) {
@@ -254,18 +275,13 @@ template <typename N, typename F> class CallGraphBuilder {
254275
template <typename N, typename F>
255276
template <typename FunctionGetter, typename InstructionGetter>
256277
[[nodiscard]] CallGraph<N, F>
257-
CallGraph<N, F>::deserialize(const nlohmann::json &PrecomputedCG,
278+
CallGraph<N, F>::deserialize(const CallGraphData &PrecomputedCG,
258279
FunctionGetter GetFunctionFromName,
259280
InstructionGetter GetInstructionFromId) {
260-
if (!PrecomputedCG.is_object()) {
261-
PHASAR_LOG_LEVEL_CAT(ERROR, "CallGraph", "Invalid Json. Expected object");
262-
return {};
263-
}
264-
265281
CallGraphBuilder<N, F> CGBuilder;
266-
CGBuilder.reserve(PrecomputedCG.size());
282+
CGBuilder.reserve(PrecomputedCG.FToFunctionVertexTy.size());
267283

268-
for (const auto &[FunName, CallerIDs] : PrecomputedCG.items()) {
284+
for (const auto &[FunName, CallerIDs] : PrecomputedCG.FToFunctionVertexTy) {
269285
const auto &Fun = std::invoke(GetFunctionFromName, FunName);
270286
if (!Fun) {
271287
PHASAR_LOG_LEVEL_CAT(WARNING, "CallGraph",
@@ -277,11 +293,10 @@ CallGraph<N, F>::deserialize(const nlohmann::json &PrecomputedCG,
277293
CEdges->reserve(CallerIDs.size());
278294

279295
for (const auto &JId : CallerIDs) {
280-
auto Id = JId.get<size_t>();
281-
const auto &CS = std::invoke(GetInstructionFromId, Id);
296+
const auto &CS = std::invoke(GetInstructionFromId, JId);
282297
if (!CS) {
283298
PHASAR_LOG_LEVEL_CAT(WARNING, "CallGraph",
284-
"Invalid CAll-Instruction Id: " << Id);
299+
"Invalid Call-Instruction Id: " << JId);
285300
}
286301

287302
CGBuilder.addCallEdge(CS, Fun);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/******************************************************************************
2+
* Copyright (c) 2024 Fabian Schiebel.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Maximilian Leo Huber and others
8+
*****************************************************************************/
9+
10+
#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
11+
#define PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H
12+
13+
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Support/raw_ostream.h"
15+
16+
#include <string>
17+
#include <unordered_map>
18+
#include <vector>
19+
20+
namespace psr {
21+
struct CallGraphData {
22+
// Mangled FunName --> [CS-IDs]
23+
std::unordered_map<std::string, std::vector<uint32_t>> FToFunctionVertexTy{};
24+
25+
CallGraphData() noexcept = default;
26+
void printAsJson(llvm::raw_ostream &OS);
27+
28+
static CallGraphData deserializeJson(const llvm::Twine &Path);
29+
static CallGraphData loadJsonString(llvm::StringRef JsonAsString);
30+
};
31+
32+
} // namespace psr
33+
34+
#endif // PHASAR_PHASARLLVM_CONTROLFLOW_CALLGRAPHDATA_H

include/phasar/ControlFlow/ICFGBase.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,23 @@ template <typename Derived> class ICFGBase {
106106
void print(llvm::raw_ostream &OS = llvm::outs()) const {
107107
self().printImpl(OS);
108108
}
109+
110+
/// Prints the underlying call-graph as Json to the given output-stream
111+
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const {
112+
self().printAsJsonImpl(OS);
113+
}
114+
109115
/// Returns the underlying call-graph as JSON
110-
[[nodiscard]] nlohmann::json getAsJson() const {
116+
[[nodiscard]] [[deprecated(
117+
"Please use printAsJson() instead")]] nlohmann::json
118+
getAsJson() const {
111119
return self().getAsJsonImpl();
112120
}
113121

122+
[[nodiscard]] size_t getNumCallSites() const noexcept {
123+
return self().getNumCallSitesImpl();
124+
}
125+
114126
private:
115127
const Derived &self() const noexcept {
116128
return static_cast<const Derived &>(*this);

include/phasar/DataFlow/IfdsIde/EdgeFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "phasar/DataFlow/IfdsIde/EdgeFunctionSingletonCache.h"
1414
#include "phasar/Utils/ByRef.h"
15+
#include "phasar/Utils/EmptyBaseOptimizationUtils.h"
1516
#include "phasar/Utils/TypeTraits.h"
1617

1718
#include "llvm/ADT/DenseMapInfo.h"
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#ifndef PHASAR_PHASARLLVM_DATAFLOWSOLVER_IFDSIDE_GENERICFLOWFUNCTION_H
2+
#define PHASAR_PHASARLLVM_DATAFLOWSOLVER_IFDSIDE_GENERICFLOWFUNCTION_H
3+
4+
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
5+
6+
namespace psr {
7+
/// Encapsulates an unmanaged pointer to a FlowFunction
8+
template <typename D, typename Container = std::set<D>>
9+
class GenericFlowFunctionView {
10+
public:
11+
using FlowFunctionType = FlowFunction<D, Container>;
12+
using FlowFunctionPtrType = std::unique_ptr<FlowFunctionType>;
13+
14+
using container_type = Container;
15+
using value_type = typename container_type::value_type;
16+
17+
GenericFlowFunctionView() noexcept = default;
18+
GenericFlowFunctionView(FlowFunctionType *FF) noexcept : FF(FF) {}
19+
20+
GenericFlowFunctionView(const GenericFlowFunctionView &) noexcept = default;
21+
GenericFlowFunctionView &
22+
operator=(const GenericFlowFunctionView &) noexcept = default;
23+
24+
~GenericFlowFunctionView() = default;
25+
26+
[[nodiscard]] container_type computeTargets(D Source) const {
27+
assert(FF != nullptr);
28+
return FF->computeTargets(std::move(Source));
29+
}
30+
31+
explicit operator bool() const noexcept { return FF; }
32+
33+
[[nodiscard]] bool operator==(GenericFlowFunctionView Other) const noexcept {
34+
return FF == Other.FF;
35+
}
36+
[[nodiscard]] bool operator==(std::nullptr_t) const noexcept {
37+
return FF == nullptr;
38+
}
39+
[[nodiscard]] bool operator!=(GenericFlowFunctionView Other) const noexcept {
40+
return !(*this == Other);
41+
}
42+
[[nodiscard]] bool operator!=(std::nullptr_t) const noexcept { return FF; }
43+
44+
private:
45+
FlowFunctionType *FF = nullptr;
46+
};
47+
48+
/// Encapsulates a managed pointer to a FlowFunction
49+
template <typename D, typename Container = std::set<D>>
50+
class GenericFlowFunction {
51+
public:
52+
using FlowFunctionType = FlowFunction<D, Container>;
53+
using FlowFunctionPtrType = typename FlowFunctionType::FlowFunctionPtrType;
54+
55+
using container_type = Container;
56+
using value_type = typename container_type::value_type;
57+
58+
GenericFlowFunction() noexcept = default;
59+
GenericFlowFunction(FlowFunctionPtrType FF) noexcept : FF(std::move(FF)) {}
60+
template <typename T, typename = std::enable_if_t<std::is_base_of_v<
61+
FlowFunctionType, std::decay_t<T>>>>
62+
GenericFlowFunction(T &&FF)
63+
: FF(std::make_unique<std::decay_t<T>>(std::forward<T>(FF))) {}
64+
65+
template <typename T, typename... ArgTys>
66+
explicit GenericFlowFunction(std::in_place_type_t<T> /*unused*/,
67+
ArgTys &&...Args)
68+
: FF(std::make_unique<T>(std::forward<ArgTys>(Args)...)) {}
69+
70+
GenericFlowFunction(GenericFlowFunction &&) noexcept = default;
71+
GenericFlowFunction &operator=(GenericFlowFunction &&) noexcept = default;
72+
73+
GenericFlowFunction(const GenericFlowFunction &) = delete;
74+
GenericFlowFunction &operator=(const GenericFlowFunction &) = delete;
75+
76+
~GenericFlowFunction() = default;
77+
78+
[[nodiscard]] container_type computeTargets(D Source) const {
79+
assert(FF != nullptr);
80+
return FF->computeTargets(std::move(Source));
81+
}
82+
83+
explicit operator bool() const noexcept { return FF; }
84+
85+
operator GenericFlowFunctionView<D, Container>() const noexcept {
86+
return FF.get();
87+
}
88+
89+
[[nodiscard]] bool
90+
operator==(GenericFlowFunctionView<D, Container> Other) const noexcept {
91+
return FF == Other.FF;
92+
}
93+
[[nodiscard]] bool operator==(std::nullptr_t) const noexcept {
94+
return FF == nullptr;
95+
}
96+
[[nodiscard]] bool
97+
operator!=(GenericFlowFunctionView<D, Container> Other) const noexcept {
98+
return !(*this == Other);
99+
}
100+
[[nodiscard]] bool operator!=(std::nullptr_t) const noexcept { return FF; }
101+
102+
private:
103+
FlowFunctionPtrType FF;
104+
};
105+
106+
} // namespace psr
107+
108+
#endif // PHASAR_PHASARLLVM_DATAFLOWSOLVER_IFDSIDE_GENERICFLOWFUNCTION_H

include/phasar/DataFlow/IfdsIde/IDETabulationProblem.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "phasar/DataFlow/IfdsIde/FlowFunctions.h"
1919
#include "phasar/DataFlow/IfdsIde/IFDSIDESolverConfig.h"
2020
#include "phasar/DataFlow/IfdsIde/InitialSeeds.h"
21+
#include "phasar/DataFlow/IfdsIde/Solver/GenericSolverResults.h"
2122
#include "phasar/DataFlow/IfdsIde/SolverResults.h"
2223
#include "phasar/Utils/JoinLattice.h"
2324
#include "phasar/Utils/NullAnalysisPrinter.h"
@@ -134,15 +135,15 @@ class IDETabulationProblem : public FlowFunctions<AnalysisDomainTy, Container>,
134135
/// Generates a text report of the results that is written to the specified
135136
/// output stream.
136137
virtual void
137-
emitTextReport([[maybe_unused]] const SolverResults<n_t, d_t, l_t> &Results,
138+
emitTextReport([[maybe_unused]] GenericSolverResults<n_t, d_t, l_t> Results,
138139
llvm::raw_ostream &OS = llvm::outs()) {
139140
OS << "No text report available!\n";
140141
}
141142

142143
/// Generates a graphical report, e.g. in html or other markup languages, of
143144
/// the results that is written to the specified output stream.
144145
virtual void emitGraphicalReport(
145-
[[maybe_unused]] const SolverResults<n_t, d_t, l_t> &Results,
146+
[[maybe_unused]] GenericSolverResults<n_t, d_t, l_t> Results,
146147
llvm::raw_ostream &OS = llvm::outs()) {
147148
OS << "No graphical report available!\n";
148149
}
@@ -151,6 +152,8 @@ class IDETabulationProblem : public FlowFunctions<AnalysisDomainTy, Container>,
151152
/// the level of soundness is ignored. Otherwise, true.
152153
virtual bool setSoundness(Soundness /*S*/) { return false; }
153154

155+
const ProjectIRDBBase<db_t> *getProjectIRDB() const noexcept { return IRDB; }
156+
154157
protected:
155158
typename FlowFunctions<AnalysisDomainTy, Container>::FlowFunctionPtrType
156159
generateFromZero(d_t FactToGenerate) {

0 commit comments

Comments
 (0)