Skip to content

Commit

Permalink
Merge remote-tracking branch 'mainline/development' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianbs96 committed Feb 2, 2024
2 parents e244eea + cd302d8 commit 27c4c49
Show file tree
Hide file tree
Showing 83 changed files with 8,929 additions and 236 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Checks: '-*,
modernize-*,
-modernize-use-trailing-return-type,
performance-*,
clang-analyzer-*,
clang-analyzer-*
'

FormatStyle: LLVM
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
-DCMAKE_BUILD_TYPE=${{ matrix.build }} \
-DBUILD_SWIFT_TESTS=ON \
-DPHASAR_DEBUG_LIBDEPS=ON \
-DPHASAR_USE_Z3=ON \
${{ matrix.flags }} \
-G Ninja
cmake --build .
Expand Down
23 changes: 21 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required (VERSION 3.9)
cmake_minimum_required (VERSION 3.14)

# Avoid IPO/LTO Warnings:
cmake_policy(SET CMP0069 NEW)
Expand Down Expand Up @@ -150,6 +150,8 @@ option(PHASAR_BUILD_UNITTESTS "Build all tests (default is ON)" ON)

option(PHASAR_BUILD_OPENSSL_TS_UNITTESTS "Build OPENSSL typestate tests (require OpenSSL, default is OFF)" OFF)

option(PHASAR_USE_Z3 "Build the phasar_llvm_pathsensitivity library with Z3 support for constraint solving (default is OFF)" OFF)

option(PHASAR_BUILD_IR "Build IR test code (default is ON)" ON)

option(PHASAR_ENABLE_CLANG_TIDY_DURING_BUILD "Run clang-tidy during build (default is OFF)" OFF)
Expand Down Expand Up @@ -259,11 +261,13 @@ add_subdirectory(external/json)
# The following workaround may collapse or become unnecessary once the issue is
# changed or fixed in nlohmann_json_schema_validator.

#Override option of nlohmann_json_schema_validator to not build its tests
# Override option of nlohmann_json_schema_validator to not build its tests
set(BUILD_TESTS OFF CACHE BOOL "Build json-schema-validator-tests")

if (PHASAR_IN_TREE)
set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS nlohmann_json_schema_validator)

set (PHASAR_USE_Z3 OFF)
endif()

# Json Schema Validator
Expand Down Expand Up @@ -337,6 +341,21 @@ if(NOT LLVM_ENABLE_RTTI AND NOT PHASAR_IN_TREE)
message(FATAL_ERROR "PhASAR requires a LLVM version that is built with RTTI")
endif()

# Z3 Solver
if(PHASAR_USE_Z3)
# This z3-version is the same version LLVM requires; however, we cannot just use Z3 via the LLVM interface
# as it lacks some functionality (such as z3::expr::simplify()) that we require
find_package(Z3 4.7.1 REQUIRED)

if(NOT TARGET z3)
add_library(z3 IMPORTED SHARED)
set_property(TARGET z3 PROPERTY
IMPORTED_LOCATION ${Z3_LIBRARIES})
set_property(TARGET z3 PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR})
endif()
endif(PHASAR_USE_Z3)

# Clang
option(BUILD_PHASAR_CLANG "Build the phasar_clang library (default is ON)" ON)

Expand Down
7 changes: 6 additions & 1 deletion Config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ find_package(LLVM 14 REQUIRED CONFIG)

set(PHASAR_USE_LLVM_FAT_LIB @USE_LLVM_FAT_LIB@)
set(PHASAR_BUILD_DYNLIB @PHASAR_BUILD_DYNLIB@)
set(PHASAR_USE_Z3 @PHASAR_USE_Z3@)

if (PHASAR_USE_Z3)
find_dependency(Z3)
endif()

set(PHASAR_COMPONENTS
utils
Expand Down Expand Up @@ -51,7 +56,7 @@ foreach(component ${phasar_FIND_COMPONENTS})
list(APPEND PHASAR_NEEDED_LIBS phasar::${component})
endforeach()

if (phasar_FOUND)
if (NOT DEFINED phasar_FOUND OR phasar_FOUND EQUAL TRUE)
foreach(component ${phasar_FIND_COMPONENTS})
# For backwards compatibility -- will be removed with next release
add_library(phasar::phasar_${component} ALIAS phasar::${component})
Expand Down
21 changes: 17 additions & 4 deletions bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ set -eo pipefail
source ./utils/safeCommandsSet.sh

readonly PHASAR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
readonly PHASAR_INSTALL_DIR="/usr/local/phasar"
readonly LLVM_INSTALL_DIR="/usr/local/llvm-14"
PHASAR_INSTALL_DIR="/usr/local/phasar"
LLVM_INSTALL_DIR="/usr/local/llvm-14"

NUM_THREADS=$(nproc)
LLVM_RELEASE=llvmorg-14.0.6
Expand All @@ -26,7 +26,8 @@ function usage {
echo -e "\t-DBOOST_DIR=<path>\t\t- The directory where boost should be installed (optional)"
echo -e "\t-DBOOST_VERSION=<string>\t- The desired boost version to install (optional)"
echo -e "\t-DCMAKE_BUILD_TYPE=<string>\t- The build mode for building PhASAR. One of {Debug, RelWithDebInfo, Release} (default is Release)"
echo -e "\t-DPHASAR_INSTALL_DIR=<path>\t- The folder where to install PhASAR if --install is specified (default is /usr/local/phasar)"
echo -e "\t-DPHASAR_INSTALL_DIR=<path>\t- The folder where to install PhASAR if --install is specified (default is ${PHASAR_INSTALL_DIR})"
echo -e "\t-DLLVM_INSTALL_DIR=<path>\t- The folder where to install LLVM if --install is specified (default is ${LLVM_INSTALL_DIR})"
}

# Parsing command-line-parameters
Expand Down Expand Up @@ -82,6 +83,15 @@ case $key in
PHASAR_INSTALL_DIR="${key#*=}"
shift # past argument=value
;;
-DLLVM_INSTALL_DIR)
LLVM_INSTALL_DIR="$2"
shift # past argument
shift # past value
;;
-DLLVM_INSTALL_DIR=*)
LLVM_INSTALL_DIR="${key#*=}"
shift # past argument=value
;;
-h|--help)
usage
exit 0
Expand Down Expand Up @@ -157,6 +167,9 @@ tmp_dir=$(mktemp -d "llvm-build.XXXXXXXX" --tmpdir)
rm -rf "${tmp_dir}"
echo "dependencies successfully installed"

# *Always* set the LLVM root to ensure the Phasar script uses the proper toolchain
LLVM_PARAMS=-DLLVM_ROOT="${LLVM_INSTALL_DIR}"

echo "Updating the submodules..."
git submodule update --init
echo "Submodules successfully updated"
Expand All @@ -169,7 +182,7 @@ export CXX=${LLVM_INSTALL_DIR}/bin/clang++

mkdir -p "${PHASAR_DIR}"/build
safe_cd "${PHASAR_DIR}"/build
cmake -G Ninja -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" "${BOOST_PARAMS}" -DPHASAR_BUILD_UNITTESTS="${DO_UNIT_TEST}" "${PHASAR_DIR}"
cmake -G Ninja -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" "${BOOST_PARAMS}" -DPHASAR_BUILD_UNITTESTS="${DO_UNIT_TEST}" "${LLVM_PARAMS}" "${PHASAR_DIR}"
cmake --build . -j "${NUM_THREADS}"

echo "phasar successfully built"
Expand Down
3 changes: 3 additions & 0 deletions include/phasar/DataFlow.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "phasar/DataFlow/IfdsIde/Solver/IDESolver.h"
#include "phasar/DataFlow/IfdsIde/Solver/IFDSSolver.h"
#include "phasar/DataFlow/IfdsIde/Solver/JumpFunctions.h"
#include "phasar/DataFlow/IfdsIde/Solver/PathAwareIDESolver.h"
#include "phasar/DataFlow/IfdsIde/Solver/PathEdge.h"
#include "phasar/DataFlow/IfdsIde/SolverResults.h"
#include "phasar/DataFlow/IfdsIde/SpecialSummaries.h"
Expand All @@ -32,5 +33,7 @@
#include "phasar/DataFlow/Mono/IntraMonoProblem.h"
#include "phasar/DataFlow/Mono/Solver/InterMonoSolver.h"
#include "phasar/DataFlow/Mono/Solver/IntraMonoSolver.h"
#include "phasar/DataFlow/PathSensitivity/PathSensitivityConfig.h"
#include "phasar/DataFlow/PathSensitivity/PathSensitivityManager.h"

#endif // PHASAR_DATAFLOW_H
22 changes: 22 additions & 0 deletions include/phasar/DataFlow/IfdsIde/Solver/ESGEdgeKind.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/******************************************************************************
* Copyright (c) 2022 Philipp Schubert.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_DATAFLOW_IFDSIDE_SOLVER_ESGEDGEKIND_H
#define PHASAR_DATAFLOW_IFDSIDE_SOLVER_ESGEDGEKIND_H

namespace psr {
enum class ESGEdgeKind { Normal, Call, CallToRet, SkipUnknownFn, Ret, Summary };

constexpr bool isInterProc(ESGEdgeKind Kind) noexcept {
return Kind == ESGEdgeKind::Call || Kind == ESGEdgeKind::Ret;
}

} // namespace psr

#endif // PHASAR_DATAFLOW_IFDSIDE_SOLVER_ESGEDGEKIND_H
32 changes: 22 additions & 10 deletions include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
#include "phasar/DataFlow/IfdsIde/IFDSTabulationProblem.h"
#include "phasar/DataFlow/IfdsIde/InitialSeeds.h"
#include "phasar/DataFlow/IfdsIde/Solver/ESGEdgeKind.h"
#include "phasar/DataFlow/IfdsIde/Solver/FlowEdgeFunctionCache.h"
#include "phasar/DataFlow/IfdsIde/Solver/IDESolverAPIMixin.h"
#include "phasar/DataFlow/IfdsIde/Solver/JumpFunctions.h"
Expand Down Expand Up @@ -297,20 +298,25 @@ class IDESolver
}
});

bool HasNoCalleeInformation = true;

// for each possible callee
for (f_t SCalledProcN : Callees) { // still line 14
// check if a special summary for the called procedure exists
FlowFunctionPtrType SpecialSum =
CachedFlowEdgeFunctions.getSummaryFlowFunction(n, SCalledProcN);

// if a special summary is available, treat this as a normal flow
// and use the summary flow and edge functions

if (SpecialSum) {
HasNoCalleeInformation = false;
PHASAR_LOG_LEVEL(DEBUG, "Found and process special summary");
for (n_t ReturnSiteN : ReturnSiteNs) {
container_type Res = computeSummaryFlowFunction(SpecialSum, d1, d2);
INC_COUNTER("SpecialSummary-FF Application", 1, Full);
ADD_TO_HISTOGRAM("Data-flow facts", Res.size(), 1, Full);
saveEdges(n, ReturnSiteN, d2, Res, false);
saveEdges(n, ReturnSiteN, d2, Res, ESGEdgeKind::Summary);
for (d_t d3 : Res) {
EdgeFunction<l_t> SumEdgFnE =
CachedFlowEdgeFunctions.getSummaryEdgeFunction(n, d2,
Expand Down Expand Up @@ -341,7 +347,8 @@ class IDESolver
}
// if startPointsOf is empty, the called function is a declaration
for (n_t SP : StartPointsOf) {
saveEdges(n, SP, d2, Res, true);
HasNoCalleeInformation = false;
saveEdges(n, SP, d2, Res, ESGEdgeKind::Call);
// for each result node of the call-flow function
for (d_t d3 : Res) {
using TableCell = typename Table<n_t, d_t, EdgeFunction<l_t>>::Cell;
Expand Down Expand Up @@ -382,7 +389,7 @@ class IDESolver
RetFunction, d3, d4, n, Container{d2});
ADD_TO_HISTOGRAM("Data-flow facts", ReturnedFacts.size(), 1,
Full);
saveEdges(eP, RetSiteN, d4, ReturnedFacts, true);
saveEdges(eP, RetSiteN, d4, ReturnedFacts, ESGEdgeKind::Ret);
// for each target value of the function
for (d_t d5 : ReturnedFacts) {
// update the caller-side summary function
Expand Down Expand Up @@ -439,7 +446,9 @@ class IDESolver
container_type ReturnFacts =
computeCallToReturnFlowFunction(CallToReturnFF, d1, d2);
ADD_TO_HISTOGRAM("Data-flow facts", ReturnFacts.size(), 1, Full);
saveEdges(n, ReturnSiteN, d2, ReturnFacts, false);
saveEdges(n, ReturnSiteN, d2, ReturnFacts,
HasNoCalleeInformation ? ESGEdgeKind::SkipUnknownFn
: ESGEdgeKind::CallToRet);
for (d_t d3 : ReturnFacts) {
EdgeFunction<l_t> EdgeFnE =
CachedFlowEdgeFunctions.getCallToRetEdgeFunction(n, d2, ReturnSiteN,
Expand Down Expand Up @@ -478,7 +487,7 @@ class IDESolver
INC_COUNTER("FF Queries", 1, Full);
const container_type Res = computeNormalFlowFunction(FlowFunc, d1, d2);
ADD_TO_HISTOGRAM("Data-flow facts", Res.size(), 1, Full);
saveEdges(n, nPrime, d2, Res, false);
saveEdges(n, nPrime, d2, Res, ESGEdgeKind::Normal);
for (d_t d3 : Res) {
EdgeFunction<l_t> g =
CachedFlowEdgeFunctions.getNormalEdgeFunction(n, d2, nPrime, d3);
Expand Down Expand Up @@ -690,12 +699,12 @@ class IDESolver
}

virtual void saveEdges(n_t SourceNode, n_t SinkStmt, d_t SourceVal,
const container_type &DestVals, bool InterP) {
const container_type &DestVals, ESGEdgeKind Kind) {
if (!SolverConfig.recordEdges()) {
return;
}
Table<n_t, n_t, std::map<d_t, container_type>> &TgtMap =
(InterP) ? ComputedInterPathEdges : ComputedIntraPathEdges;
(isInterProc(Kind)) ? ComputedInterPathEdges : ComputedIntraPathEdges;
TgtMap.get(SourceNode, SinkStmt)[SourceVal].insert(DestVals.begin(),
DestVals.end());
}
Expand All @@ -716,7 +725,10 @@ class IDESolver
<< ", value: " << LToString(Value));
// initialize the initial seeds with the top element as we have no
// information at the beginning of the value computation problem
setVal(StartPoint, Fact, Value);
l_t OldVal = val(StartPoint, Fact);
auto NewVal = IDEProblem.join(Value, std::move(OldVal));
setVal(StartPoint, Fact, std::move(NewVal));

std::pair<n_t, d_t> SuperGraphNode(StartPoint, Fact);
valuePropagationTask(std::move(SuperGraphNode));
}
Expand Down Expand Up @@ -833,7 +845,7 @@ class IDESolver
const container_type Targets =
computeReturnFlowFunction(RetFunction, d1, d2, c, Entry.second);
ADD_TO_HISTOGRAM("Data-flow facts", Targets.size(), 1, Full);
saveEdges(n, RetSiteC, d2, Targets, true);
saveEdges(n, RetSiteC, d2, Targets, ESGEdgeKind::Ret);
// for each target value at the return site
// line 23
for (d_t d5 : Targets) {
Expand Down Expand Up @@ -902,7 +914,7 @@ class IDESolver
const container_type Targets = computeReturnFlowFunction(
RetFunction, d1, d2, Caller, Container{ZeroValue});
ADD_TO_HISTOGRAM("Data-flow facts", Targets.size(), 1, Full);
saveEdges(n, RetSiteC, d2, Targets, true);
saveEdges(n, RetSiteC, d2, Targets, ESGEdgeKind::Ret);
for (d_t d5 : Targets) {
EdgeFunction<l_t> f5 =
CachedFlowEdgeFunctions.getReturnEdgeFunction(
Expand Down
69 changes: 69 additions & 0 deletions include/phasar/DataFlow/IfdsIde/Solver/PathAwareIDESolver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/******************************************************************************
* Copyright (c) 2022 Philipp Schubert.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_DATAFLOW_IFDSIDE_SOLVER_PATHAWAREIDESOLVER_H
#define PHASAR_DATAFLOW_IFDSIDE_SOLVER_PATHAWAREIDESOLVER_H

#include "phasar/DataFlow/IfdsIde/IDETabulationProblem.h"
#include "phasar/DataFlow/IfdsIde/Solver/ESGEdgeKind.h"
#include "phasar/DataFlow/IfdsIde/Solver/IDESolver.h"
#include "phasar/DataFlow/PathSensitivity/ExplodedSuperGraph.h"
#include "phasar/Utils/Logger.h"

namespace psr {
template <typename AnalysisDomainTy,
typename Container = std::set<typename AnalysisDomainTy::d_t>>
class PathAwareIDESolver : public IDESolver<AnalysisDomainTy, Container> {
using base_t = IDESolver<AnalysisDomainTy, Container>;

public:
using domain_t = AnalysisDomainTy;
using n_t = typename base_t::n_t;
using d_t = typename base_t::d_t;
using i_t = typename base_t::i_t;
using container_type = typename base_t::container_type;

explicit PathAwareIDESolver(
IDETabulationProblem<domain_t, container_type> &Problem, const i_t *ICF)
: base_t(Problem, ICF), ESG(Problem.getZeroValue()) {

if (Problem.getIFDSIDESolverConfig().autoAddZero()) {
PHASAR_LOG_LEVEL(
WARNING,
"The PathAwareIDESolver is initialized with the option 'autoAddZero' "
"being set. This might degrade the quality of the computed paths!");
}
}

[[nodiscard]] const ExplodedSuperGraph<domain_t> &
getExplicitESG() const &noexcept {
return ESG;
}

[[nodiscard]] ExplodedSuperGraph<domain_t> &&getExplicitESG() &&noexcept {
return std::move(ESG);
}

private:
void saveEdges(n_t Curr, n_t Succ, d_t CurrNode,
const container_type &SuccNodes, ESGEdgeKind Kind) override {
ESG.saveEdges(std::move(Curr), std::move(CurrNode), std::move(Succ),
SuccNodes, Kind);
}

ExplodedSuperGraph<domain_t> ESG;
};

template <typename ProblemTy>
PathAwareIDESolver(ProblemTy &)
-> PathAwareIDESolver<typename ProblemTy::ProblemAnalysisDomain>;

} // namespace psr

#endif // PHASAR_DATAFLOW_IFDSIDE_SOLVER_PATHAWAREIDESOLVER_H
1 change: 1 addition & 0 deletions include/phasar/DataFlow/IfdsIde/SolverResults.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class OwningSolverResults
[[nodiscard]] operator SolverResults<N, D, L>() const &noexcept {
return get();
}

operator SolverResults<N, D, L>() && = delete;

private:
Expand Down
Loading

0 comments on commit 27c4c49

Please sign in to comment.