Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-24.04, ubuntu-24.04-arm]
compiler: [ [clang++-19, clang-19, "clang-19 libclang-rt-19-dev clang-tools-19"] ]
compiler: [ [clang++-20, clang-20, "clang-20 libclang-rt-20-dev clang-tools-20"] ]
build: [ Debug, Release, DebugLibdeps, DebugCov ]
llvm-version: [ 16, 17 ]
llvm-version: [ 16, "22.1" ]
include:
- build: Debug
cmake_build_type: Debug
Expand All @@ -31,7 +31,11 @@ jobs:
- build: DebugCov
cmake_build_type: Debug
flags: -DCODE_COVERAGE=ON
extra_dependencies: llvm-19 # For coverage
extra_dependencies: llvm-20 # For coverage
- llvm-version: 16
llvm-major-version: 16
- llvm-version: "22.1"
llvm-major-version: 22
exclude:
- os: ubuntu-24.04-arm
build: Debug
Expand All @@ -43,7 +47,7 @@ jobs:
continue-on-error: false
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: recursive
Expand All @@ -56,7 +60,7 @@ jobs:
- name: Install Phasar Dependencies
shell: bash
run: |
./utils/InstallAptDependencies.sh --llvm-version ${{ matrix.llvm-version }} --noninteractive tzdata ccache ${{ matrix.compiler[2] }} ${{ matrix.extra_dependencies }}
./utils/InstallAptDependencies.sh --llvm-version ${{ matrix.llvm-major-version }} --noninteractive tzdata ccache ${{ matrix.compiler[2] }} ${{ matrix.extra_dependencies }}

- name: Building Phasar in ${{ matrix.build }} with ${{ matrix.compiler[0] }}
env:
Expand Down Expand Up @@ -102,7 +106,7 @@ jobs:

- name: Upload coverage HTML report artifact
if: matrix.build == 'DebugCov'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: phasar-coverage-report-llvm-${{ matrix.llvm-version }}
path: ./build/ccov/all-merged/
Expand Down
29 changes: 16 additions & 13 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
It is recommended to compile PhASAR yourself in order to get the full C++ experience and to have full control over the build mode.
However, you may also want to try out one of the pre-built versions of PhASAR or the Docker container.

As a shortcut for the very first PhASAR build on your system, you can use our [bootstrap](./bootstrap.sh) script.
As a shortcut for the very first PhASAR build on your system, you can use our [bootstrap](./bootstrap.sh) script.<br>
**For subsequent builds**, see [Compiling PhASAR](#compiling-phasar-if-not-already-done-using-the-bootstrap-script).

Please note that you must have python installed for the script to work properly.

```bash
Expand All @@ -19,11 +21,10 @@ Note: If you want to do changes within PhASAR, it is recommended to build it in

The bootstrap script may ask for superuser permissions (to install the dependencies); however it is not recommended to start the whole script with `sudo`.

For subsequent builds, see [Compiling PhASAR](#compiling-phasar-if-not-already-done-using-the-installation-scripts).

### Compiling PhASAR (if not already done using the bootstrap script)

Set the system's variables for the C and C++ compiler to clang:
Set the system's variables for the C and C++ compiler to clang (gcc should also work, but we strongly recommend clang):

```bash
export CC=/usr/local/bin/clang
Expand All @@ -45,21 +46,24 @@ utils/init-submodules-release.sh
Navigate into the PhASAR directory. The following commands will do the job and compile the PhASAR framework:

```bash
mkdir build
mkdir -p build
cd build/
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release .. # ninja is not required, but recommended for
# build-performance
ninja -j $(nproc) # or use a different number of cores to compile it
sudo ninja install # only if you wish to install PhASAR system wide
```

When you have used the `bootstrap.sh` script to install PhASAR, the above steps are already done.
Use them as a reference if you wish to modify PhASAR and recompile it.

After compilation using cmake the following two binaries can be found in the build/tools directory:
After compilation using cmake the following two binaries can be found in the `build/tools` directory:

+ `phasar-cli` - the PhASAR command-line tool (previously called `phasar-llvm`) that provides access to analyses that are already implemented within PhASAR. Use this if you don't want to build an own tool on top of PhASAR.
+ `myphasartool` - an example tool that shows how tools can be build on top of PhASAR

Also, find the `libphasar.a` or `libphasar.so` library in `build/lib/`.

Please be careful and check if errors occur during the compilation.

When using CMake to compile PhASAR the following optional parameters can be used:
Expand All @@ -80,7 +84,7 @@ When using CMake to compile PhASAR the following optional parameters can be used
| **PHASAR_ENABLE_PIC** : BOOL | Build Position-Independed Code (default is ON) |
| **PHASAR_ENABLE_WARNINGS** : BOOL | Enable compiler warnings (default is ON) |
| **CMAKE_CXX_STANDARD** : INT|Adapt the used C++ standard (minimum required is 20)|
| **PHASAR_LLVM_VERSION** : INT|The LLVM major-version to use. Can be 16 or 17 (default is 16)|
| **PHASAR_LLVM_VERSION** : VERSION|The LLVM major-version to use. Can be between 16 and 22.1 (default is 16)|

You can use these parameters either directly or modify the installer-script `bootstrap.sh`

Expand All @@ -90,13 +94,12 @@ C++'s long compile times are always a pain. As shown in the above, when using cm

### Running a Test Solver

To test if everything works as expected please run the following command:

`$ phasar-cli -m test/llvm_test_code/basic/module_cpp.ll -D ifds-solvertest`
To test if everything works as expected please run the following command (from the `build/` folder):

You can find the `phasar-cli` tool in the build-tree under `tools/phasar-cli`.
`$ ./tools/phasar-cli/phasar-cli -m test/llvm_test_code/basic/module_cpp.ll -D ifds-solvertest --emit-raw-results`

If you obtain output other than a segmentation fault or an exception terminating the program abnormally everything works as expected.
The output should show that the `@zero_value` data-flow fact holds at every LLVM instruction in the module.
Especially, there should be no segmentation fault, exception, or other non-zero exit condition.

### Building PhASAR on a MacOS System

Expand All @@ -107,7 +110,7 @@ Now you can just attach your docker container to VS Code or any other IDE, which
## Installation

PhASAR can be installed using the installer scripts as explained in the following.
However, you do not need to install PhASAR in order to use it.
However, **you do not need to install PhASAR in order to use it**.

### Installing PhASAR on an Ubuntu System

Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ FROM "$baseimage" AS build

RUN --mount=type=bind,source=./utils/InstallAptDependencies.sh,target=/InstallAptDependencies.sh \
set -eux; \
./InstallAptDependencies.sh --noninteractive tzdata clang-19 libclang-rt-19-dev clang-tools-19
./InstallAptDependencies.sh --noninteractive tzdata clang-20 libclang-rt-20-dev clang-tools-20

ENV CC=/usr/bin/clang-19 \
CXX=/usr/bin/clang++-19
ENV CC=/usr/bin/clang-20 \
CXX=/usr/bin/clang++-20

FROM build

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ PhASAR supports C++20 modules as an experimental feature.

## Currently Supported Version of LLVM

**NEW**: PhASAR is currently set up to support **LLVM-16 and 17**, using LLVM 16 by default.<br>
**NEW**: PhASAR is currently set up to support LLVM versions **between LLVM-16 and LLVM-22.1**, using LLVM 16 by default. We actively test PHASAR with LLVM-16 and LLVM-22.1, so if something does not work, try these versions instead.<br>
Specify the `PHASAR_LLVM_VERSION` cmake-variable to change the LLVM version to use.


Expand Down
4 changes: 2 additions & 2 deletions examples/how-to/00-load-llvm-ir/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ target_link_libraries(load-llvm-ir PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_load_llvm_ir
DEPENDS load-llvm-ir
COMMAND $<TARGET_FILE:load-llvm-ir> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/simple.ll"
DEPENDS load-llvm-ir LLFileGeneration
COMMAND $<TARGET_FILE:load-llvm-ir> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/simple_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_load_llvm_ir)
Expand Down
4 changes: 2 additions & 2 deletions examples/how-to/01-build-type-hierarchy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ target_link_libraries(build-type-hierarchy PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_build_type_hierarchy
DEPENDS build-type-hierarchy
COMMAND $<TARGET_FILE:build-type-hierarchy> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/class_hierarchy.ll"
DEPENDS build-type-hierarchy LLFileGeneration
COMMAND $<TARGET_FILE:build-type-hierarchy> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/class_hierarchy_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_build_type_hierarchy)
Expand Down
6 changes: 3 additions & 3 deletions examples/how-to/02-build-call-graph/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ target_link_libraries(build-llvm-based-call-graph PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_build_call_graph
DEPENDS build-llvm-based-icfg build-llvm-based-call-graph
COMMAND $<TARGET_FILE:build-llvm-based-icfg> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/class_hierarchy.ll"
COMMAND $<TARGET_FILE:build-llvm-based-call-graph> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/class_hierarchy.ll"
DEPENDS build-llvm-based-icfg build-llvm-based-call-graph LLFileGeneration
COMMAND $<TARGET_FILE:build-llvm-based-icfg> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/class_hierarchy_cpp_dbg.ll"
COMMAND $<TARGET_FILE:build-llvm-based-call-graph> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/class_hierarchy_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_build_call_graph)
Expand Down
4 changes: 2 additions & 2 deletions examples/how-to/03-create-alias-info/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ target_link_libraries(create-alias-info PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_create_alias_info
DEPENDS create-alias-info
COMMAND $<TARGET_FILE:create-alias-info> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/pointers.ll"
DEPENDS create-alias-info LLFileGeneration
COMMAND $<TARGET_FILE:create-alias-info> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/pointers_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_create_alias_info)
Expand Down
10 changes: 5 additions & 5 deletions examples/how-to/04-run-ifds-analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ target_link_libraries(run-ifds-analysis-ifds-solver PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_run_ifds_analysis
DEPENDS run-ifds-analysis-simple run-ifds-analysis-helper-analyses run-ifds-analysis-otf-reporter run-ifds-analysis-ifds-solver
COMMAND $<TARGET_FILE:run-ifds-analysis-simple> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-helper-analyses> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-otf-reporter> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-ifds-solver> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
DEPENDS run-ifds-analysis-simple run-ifds-analysis-helper-analyses run-ifds-analysis-otf-reporter run-ifds-analysis-ifds-solver LLFileGeneration
COMMAND $<TARGET_FILE:run-ifds-analysis-simple> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-helper-analyses> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-otf-reporter> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
COMMAND $<TARGET_FILE:run-ifds-analysis-ifds-solver> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_run_ifds_analysis)
Expand Down
8 changes: 4 additions & 4 deletions examples/how-to/05-run-ide-analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ target_link_libraries(run-ide-analysis-ide-solver PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_run_ide_analysis
DEPENDS run-ide-analysis-simple run-ide-analysis-helper-analyses run-ide-analysis-ide-solver
COMMAND $<TARGET_FILE:run-ide-analysis-simple> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/call2.ll"
COMMAND $<TARGET_FILE:run-ide-analysis-helper-analyses> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/call2.ll"
COMMAND $<TARGET_FILE:run-ide-analysis-ide-solver> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/call2.ll"
DEPENDS run-ide-analysis-simple run-ide-analysis-helper-analyses run-ide-analysis-ide-solver LLFileGeneration
COMMAND $<TARGET_FILE:run-ide-analysis-simple> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/call2_cpp_dbg.ll"
COMMAND $<TARGET_FILE:run-ide-analysis-helper-analyses> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/call2_cpp_dbg.ll"
COMMAND $<TARGET_FILE:run-ide-analysis-ide-solver> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/call2_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_run_ide_analysis)
Expand Down
4 changes: 2 additions & 2 deletions examples/how-to/07-write-ifds-analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ target_link_libraries(write-ifds-analysis-simple PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_write_ifds_analysis
DEPENDS write-ifds-analysis-simple
COMMAND $<TARGET_FILE:write-ifds-analysis-simple> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
DEPENDS write-ifds-analysis-simple LLFileGeneration
COMMAND $<TARGET_FILE:write-ifds-analysis-simple> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_write_ifds_analysis)
Expand Down
4 changes: 2 additions & 2 deletions examples/how-to/08-write-ide-analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ target_link_libraries(write-ide-analysis-simple PRIVATE phasar::phasar)

if (TARGET run_sample_programs)
add_custom_target(run_write_ide_analysis
DEPENDS write-ide-analysis-simple
COMMAND $<TARGET_FILE:write-ide-analysis-simple> "${CMAKE_CURRENT_LIST_DIR}/../../llvm-hello-world/target/taint.ll"
DEPENDS write-ide-analysis-simple LLFileGeneration
COMMAND $<TARGET_FILE:write-ide-analysis-simple> "${CMAKE_CURRENT_BINARY_DIR}/../llvm-hello-world/target/taint_cpp_dbg.ll"
)

add_dependencies(run_sample_programs run_write_ide_analysis)
Expand Down
5 changes: 5 additions & 0 deletions examples/how-to/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ foreach(child ${children})
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/${child})
endif()
endforeach()

find_package(phasar REQUIRED CONFIG)

message("PHASAR_LLVM_VERSION LLVM-${PHASAR_LLVM_VERSION}")
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../llvm-hello-world ${CMAKE_CURRENT_BINARY_DIR}/llvm-hello-world)
9 changes: 8 additions & 1 deletion examples/llvm-hello-world/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ project(llvm-hello-world)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(LLVM 15 REQUIRED CONFIG)
set(LLVM_HW_LLVM_VERSION 15)
if(PHASAR_LLVM_VERSION)
set(LLVM_HW_LLVM_VERSION ${PHASAR_LLVM_VERSION})
endif()

message(STATUS "llvm-hello-world: Use LLVM-${LLVM_HW_LLVM_VERSION}")

find_package(LLVM ${LLVM_HW_LLVM_VERSION} REQUIRED CONFIG)

add_executable(main main.cpp)
target_link_libraries(main PRIVATE LLVMCore LLVMIRReader)
Expand Down
4 changes: 3 additions & 1 deletion examples/llvm-hello-world/target/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ add_custom_target(LLFileGeneration ALL)
# Use phasar's capabilities to automate the LLVM-IR file generation

include(../../../cmake/phasar_macros.cmake)
set(PHASAR_LLVM_VERSION 15)
if (NOT PHASAR_LLVM_VERSION)
set(PHASAR_LLVM_VERSION 15)
endif()

file(GLOB target_files RELATIVE ${CMAKE_CURRENT_LIST_DIR} *.cpp)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,13 @@ class PathSensitivityManagerMixin {
return pathsDagToAll(Inst, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}

if (auto Next = Inst->getNextNonDebugInstruction()) {
if (auto Next =
#if LLVM_VERSION_MAJOR <= 18
Inst->getNextNonDebugInstruction()
#else
Inst->getNextNode()
#endif
) {
return pathsDagToAll(Next, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}

Expand All @@ -203,9 +209,11 @@ class PathSensitivityManagerMixin {

for (const auto *BB : llvm::successors(Inst)) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
if (ESG.getNodeOrNull(First, Fact)) {
return pathsDagToAll(First, llvm::ArrayRef(&Fact, 1), Config, PFilter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ namespace psr::detail {
if (!Stmt->getNextNode()) {
auto GetStartRow = [&Self](const llvm::BasicBlock *BB) -> decltype(auto) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
return Self.row(First);
};

Expand Down Expand Up @@ -104,9 +106,11 @@ namespace psr::detail {
auto GetStartVal = [&Self,
&Fact](const llvm::BasicBlock *BB) -> decltype(auto) {
const auto *First = &BB->front();
#if LLVM_VERSION_MAJOR <= 18
if (llvm::isa<llvm::DbgInfoIntrinsic>(First)) {
First = First->getNextNonDebugInstruction();
}
#endif
return Self.resultAt(First, Fact);
};

Expand Down
6 changes: 6 additions & 0 deletions include/phasar/PhasarLLVM/Utils/LLVMShorthands.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ bool isHeapAllocatingFunction(const llvm::Function *F) noexcept;
///
/// \note This function is less useful in practice than you may think. Consider
/// using isConsistentCall() instead.
LLVM_DEPRECATED("With opaque pointers, this function is not very useful. Use "
"isConsistentCall() instead.",
"psr::isConsistentCall")
bool matchesSignature(const llvm::Function *F, const llvm::FunctionType *FType,
bool ExactMatch = true);

Expand All @@ -79,6 +82,9 @@ bool matchesSignature(const llvm::Function *F, const llvm::FunctionType *FType,
///
/// \note This function is less useful in practice than you may think. Consider
/// using isConsistentCall() instead.
LLVM_DEPRECATED("With opaque pointers, this function is not very useful. Use "
"isConsistentCall() instead.",
"psr::isConsistentCall")
bool matchesSignature(const llvm::FunctionType *FType1,
const llvm::FunctionType *FType2);

Expand Down
7 changes: 3 additions & 4 deletions lib/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,9 @@ bool GlobalCtorsDtorsModel::isPhasarGenerated(
const llvm::Function &F) noexcept {
if (F.hasName()) {
llvm::StringRef FunctionName = F.getName();
return llvm::StringSwitch<bool>(FunctionName)
.Cases(ModelName, DtorModelName, DtorsCallerName, UserEntrySelectorName,
true)
.Default(false);
const auto Cases = {ModelName, DtorModelName, DtorsCallerName,
UserEntrySelectorName};
return llvm::is_contained(Cases, FunctionName);
}

return false;
Expand Down
Loading
Loading