Skip to content

Commit 6ac85b2

Browse files
authored
Merge pull request #430 from secure-software-engineering/f-SolverConfigParams
SolverConfig Parametrization
2 parents de7532a + f103b86 commit 6ac85b2

9 files changed

Lines changed: 172 additions & 105 deletions

File tree

include/phasar/Controller/AnalysisController.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "phasar/DB/ProjectIRDB.h"
2121
#include "phasar/PhasarLLVM/AnalysisStrategy/Strategies.h"
2222
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h"
23+
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"
2324
#include "phasar/PhasarLLVM/Pointer/LLVMBasedPointsToAnalysis.h"
2425
#include "phasar/PhasarLLVM/Pointer/LLVMPointsToSet.h"
2526
#include "phasar/PhasarLLVM/TypeHierarchy/LLVMTypeHierarchy.h"
@@ -62,6 +63,7 @@ class AnalysisController {
6263
std::string ProjectID;
6364
std::string OutDirectory;
6465
boost::filesystem::path ResultDirectory;
66+
IFDSIDESolverConfig SolverConfig;
6567
[[maybe_unused]] Soundness SoundnessLevel;
6668
[[maybe_unused]] bool AutoGlobalSupport;
6769

@@ -122,6 +124,7 @@ class AnalysisController {
122124
const std::set<std::string> &EntryPoints,
123125
AnalysisStrategy Strategy,
124126
AnalysisControllerEmitterOptions EmitterOptions,
127+
IFDSIDESolverConfig SolverConfig,
125128
const std::string &ProjectID = "default-phasar-project",
126129
const std::string &OutDirectory = "");
127130

include/phasar/PhasarLLVM/AnalysisStrategy/WholeProgramAnalysis.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "phasar/DB/ProjectIRDB.h"
2121
#include "phasar/PhasarLLVM/AnalysisStrategy/AnalysisSetup.h"
22+
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"
23+
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Solver/IDESolver.h"
2224

2325
namespace psr {
2426

@@ -51,7 +53,7 @@ class WholeProgramAnalysis {
5153
Solver DataFlowSolver;
5254

5355
public:
54-
WholeProgramAnalysis(ProjectIRDB &IRDB,
56+
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
5557
std::set<std::string> EntryPoints = {},
5658
PointerAnalysisTy *PointerInfo = nullptr,
5759
CallGraphAnalysisTy *CallGraph = nullptr,
@@ -70,12 +72,17 @@ class WholeProgramAnalysis {
7072
: std::unique_ptr<CallGraphAnalysisTy>(CallGraph)),
7173
EntryPoints(EntryPoints),
7274
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, EntryPoints),
73-
DataFlowSolver(ProblemDesc) {}
75+
DataFlowSolver(ProblemDesc) {
76+
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
77+
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
78+
}
79+
}
7480

7581
template <typename T = ProblemDescription,
7682
typename = typename std::enable_if_t<!std::is_same_v<
7783
typename T::ConfigurationTy, HasNoConfigurationType>>>
78-
WholeProgramAnalysis(ProjectIRDB &IRDB, ConfigurationTy *Config,
84+
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
85+
ConfigurationTy *Config,
7986
std::set<std::string> EntryPoints = {},
8087
PointerAnalysisTy *PointerInfo = nullptr,
8188
CallGraphAnalysisTy *CallGraph = nullptr,
@@ -95,12 +102,17 @@ class WholeProgramAnalysis {
95102
EntryPoints(EntryPoints), Config(Config),
96103
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, *Config,
97104
EntryPoints),
98-
DataFlowSolver(ProblemDesc) {}
105+
DataFlowSolver(ProblemDesc) {
106+
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
107+
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
108+
}
109+
}
99110

100111
template <typename T = ProblemDescription,
101112
typename = typename std::enable_if_t<!std::is_same_v<
102113
typename T::ConfigurationTy, HasNoConfigurationType>>>
103-
WholeProgramAnalysis(ProjectIRDB &IRDB, std::string ConfigPath,
114+
WholeProgramAnalysis(IFDSIDESolverConfig SolverConfig, ProjectIRDB &IRDB,
115+
std::string ConfigPath,
104116
std::set<std::string> EntryPoints = {},
105117
PointerAnalysisTy *PointerInfo = nullptr,
106118
CallGraphAnalysisTy *CallGraph = nullptr,
@@ -121,7 +133,11 @@ class WholeProgramAnalysis {
121133
OwnsConfig(true), ConfigPath(ConfigPath),
122134
ProblemDesc(&IRDB, TypeHierarchy, CallGraph, PointerInfo, *Config,
123135
EntryPoints),
124-
DataFlowSolver(ProblemDesc) {}
136+
DataFlowSolver(ProblemDesc) {
137+
if constexpr (has_setIFDSIDESolverConfig_v<ProblemDescription>) {
138+
ProblemDesc.setIFDSIDESolverConfig(SolverConfig);
139+
}
140+
}
125141

126142
WholeProgramAnalysis(const WholeProgramAnalysis &) = delete;
127143
WholeProgramAnalysis(WholeProgramAnalysis &&) = delete;

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "phasar/Config/Configuration.h"
2323
#include "phasar/Utils/EnumFlags.h"
2424
#include "phasar/Utils/Logger.h"
25-
#include "phasar/Utils/Utilities.h"
2625

2726
namespace psr {
2827

@@ -39,13 +38,14 @@ enum class SolverConfigOptions : uint32_t {
3938
};
4039

4140
struct IFDSIDESolverConfig {
42-
IFDSIDESolverConfig();
43-
IFDSIDESolverConfig(SolverConfigOptions Options);
41+
IFDSIDESolverConfig() noexcept = default;
42+
IFDSIDESolverConfig(SolverConfigOptions Options) noexcept;
4443
~IFDSIDESolverConfig() = default;
45-
IFDSIDESolverConfig(const IFDSIDESolverConfig &) = default;
46-
IFDSIDESolverConfig &operator=(const IFDSIDESolverConfig &) = default;
47-
IFDSIDESolverConfig(IFDSIDESolverConfig &&) = default;
48-
IFDSIDESolverConfig &operator=(IFDSIDESolverConfig &&) = default;
44+
IFDSIDESolverConfig(const IFDSIDESolverConfig &) noexcept = default;
45+
IFDSIDESolverConfig &
46+
operator=(const IFDSIDESolverConfig &) noexcept = default;
47+
IFDSIDESolverConfig(IFDSIDESolverConfig &&) noexcept = default;
48+
IFDSIDESolverConfig &operator=(IFDSIDESolverConfig &&) noexcept = default;
4949

5050
[[nodiscard]] bool followReturnsPastSeeds() const;
5151
[[nodiscard]] bool autoAddZero() const;
@@ -61,6 +61,8 @@ struct IFDSIDESolverConfig {
6161
void setEmitESG(bool Set = true);
6262
void setComputePersistedSummaries(bool Set = true);
6363

64+
void setConfig(SolverConfigOptions Opt);
65+
6466
friend std::ostream &operator<<(std::ostream &OS,
6567
const IFDSIDESolverConfig &SC);
6668

include/phasar/Utils/TypeTraits.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <type_traits>
1616
#include <variant>
1717

18+
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/IFDSIDESolverConfig.h"
19+
1820
#include "llvm/Support/raw_ostream.h"
1921

2022
namespace psr {
@@ -75,6 +77,13 @@ template <typename T>
7577
struct is_llvm_hashable<T, decltype(hash_value(std::declval<T>()))> // NOLINT
7678
: std::true_type {};
7779

80+
template <typename T, typename = void>
81+
struct has_setIFDSIDESolverConfig : std::false_type {};
82+
template <typename T>
83+
struct has_setIFDSIDESolverConfig<
84+
T, decltype(std::declval<T>().setIFDSIDESolverConfig(
85+
std::declval<IFDSIDESolverConfig>()))> : std::true_type {};
86+
7887
} // namespace detail
7988

8089
template <typename T>
@@ -111,6 +120,10 @@ template <typename T>
111120
constexpr bool is_llvm_hashable_v = // NOLINT
112121
detail::is_llvm_hashable<T>::value;
113122

123+
template <typename T>
124+
constexpr bool has_setIFDSIDESolverConfig_v = // NOLINT
125+
detail::has_setIFDSIDESolverConfig<T>::value;
126+
114127
template <typename T> struct is_variant : std::false_type {}; // NOLINT
115128

116129
template <typename... Args>

include/phasar/Utils/Utilities.h

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -197,41 +197,48 @@ It remove_by_index(It First, EndIt Last, IdxIt FirstIndex, IdxEndIt LastIndex) {
197197
if (FirstIndex == LastIndex || First == Last) {
198198
return Last;
199199
}
200-
First = std::next(First, *FirstIndex);
201-
if (First == Last) {
202-
return First;
203-
}
204-
205-
auto CurrIdx = *FirstIndex;
206200

207201
if constexpr (std::is_same_v<It, EndIt> &&
208202
std::is_same_v<
209203
std::random_access_iterator_tag,
210204
typename std::iterator_traits<It>::iterator_category>) {
211-
size_t GapSize = 1;
212-
auto Curr = First + 1;
205+
/// Random-access version inspired from
206+
/// "https://codereview.stackexchange.com/a/207056" and slightly changed
213207

208+
auto Bounds = size_t(std::distance(First, Last));
209+
auto Out = std::next(First, *FirstIndex);
210+
auto In = std::next(Out);
214211
while (++FirstIndex != LastIndex) {
215-
auto Offset = *FirstIndex - CurrIdx - 1;
216-
if (Offset >= std::distance(Curr, Last)) {
212+
auto CurrIdx = *FirstIndex;
213+
if (*std::prev(FirstIndex) + 1 == CurrIdx) {
214+
++In;
215+
continue;
216+
}
217+
if (LLVM_UNLIKELY(CurrIdx >= Bounds)) {
217218
break;
218219
}
219-
First = std::move(Curr, Curr + Offset, First); // NOLINT
220-
CurrIdx = *FirstIndex;
221-
Curr = First + ++GapSize;
222-
}
223220

224-
return std::move(Curr, Last, First); // NOLINT
225-
}
226-
for (auto I = First; I != Last; ++CurrIdx, ++I) {
227-
if (CurrIdx != *FirstIndex) {
228-
*First++ = std::move(*I);
229-
if (++FirstIndex == LastIndex) {
230-
return std::move(std::next(I), Last, First);
221+
auto Tar = std::next(First, CurrIdx);
222+
Out = std::move(In, Tar, Out);
223+
In = std::next(Tar);
224+
}
225+
return std::move(In, Last, Out);
226+
} else {
227+
auto CurrIdx = *FirstIndex;
228+
First = std::next(First, CurrIdx);
229+
if (First == Last) {
230+
return First;
231+
}
232+
for (auto I = First; I != Last; ++CurrIdx, ++I) {
233+
if (CurrIdx != *FirstIndex) {
234+
*First++ = std::move(*I);
235+
if (++FirstIndex == LastIndex) {
236+
return std::move(std::next(I), Last, First);
237+
}
231238
}
232239
}
240+
return First;
233241
}
234-
return First;
235242
}
236243

237244
template <typename Container, typename IdxIt,

0 commit comments

Comments
 (0)