diff --git a/.clang-format b/.clang-format index 07058b4e..26f1fa70 100644 --- a/.clang-format +++ b/.clang-format @@ -1,10 +1,10 @@ -Language: Cpp +Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: true AlignEscapedNewlinesLeft: true -AlignOperands: true +AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false @@ -20,7 +20,7 @@ BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BinPackParameters: true BinPackArguments: true -ColumnLimit: 120 +ColumnLimit: 120 ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 DerivePointerAlignment: false @@ -43,31 +43,31 @@ PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left SpacesBeforeTrailingComments: 2 Cpp11BracedListStyle: true -Standard: Cpp11 -IndentWidth: 2 -TabWidth: 2 -UseTab: Never +Standard: Cpp11 +IndentWidth: 2 +TabWidth: 2 +UseTab: Never BreakBeforeBraces: Attach SpacesInParentheses: false SpacesInSquareBrackets: false -SpacesInAngles: false +SpacesInAngles: false SpaceInEmptyParentheses: false SpacesInCStyleCastParentheses: false SpaceAfterCStyleCast: false SpacesInContainerLiterals: true SpaceBeforeAssignmentOperators: true ContinuationIndentWidth: 4 -CommentPragmas: '^ IWYU pragma:' -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] SpaceBeforeParens: ControlStatements -DisableFormat: false +DisableFormat: false IncludeBlocks: Regroup IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - - Regex: '<[[:alnum:].]+>' - Priority: 4 - - Regex: '.*' - Priority: 1 + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '<[[:alnum:].]+>' + Priority: 4 + - Regex: '.*' + Priority: 1 diff --git a/.github/workflows/basic-ci.yml b/.github/workflows/basic-ci.yml index 23b1b72d..dddc6c74 100644 --- a/.github/workflows/basic-ci.yml +++ b/.github/workflows/basic-ci.yml @@ -8,24 +8,106 @@ on: env: CXX: clang++-10 CC: clang-10 + EXTERNAL_LIT: /usr/lib/llvm-10/build/utils/lit/lit.py + OMP_NUM_THREAD: 2 jobs: - build-and-run-test: + format-check: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + + - name: Format source code + run: | + find demo lib test \ + -type f \ + -a \( -name "*.c" -o -name "*.cpp" -o -name "*.h" \) \ + -not -path "*/lulesh/*" \ + -print0 \ + | xargs -0 clang-format-10 -i + + - name: List newly formatted files + run: git status --porcelain --untracked-files=no + + - name: Check format + run: git status --porcelain --untracked-files=no | xargs -o -I {} test -z \"{}\" + + lit-suite: runs-on: ubuntu-20.04 if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + fail-fast: false + matrix: + config: + - { + name: Thread-safe-safeptr, + build_type: Debug, + safe_ptr: true, + tsan: true, + } + - { + name: Thread-safe, + build_type: Debug, + safe_ptr: false, + tsan: true, + } + - { + name: Thread-unsafe, + build_type: Debug, + thread_unsafe: true, + tsan: false, + } + - { + name: Coverage-thread-safe-safeptr, + build_type: Debug, + safe_ptr: true, + coverage: true, + tsan: false, + } + - { + name: Coverage-thread-safe, + build_type: Debug, + safe_ptr: false, + coverage: true, + tsan: false, + } + - { + name: Coverage-thread-unsafe, + build_type: Debug, + thread_unsafe: true, + coverage: true, + tsan: false, + } + - { + name: Thread-safe-libc++, + build_type: Debug, + cxxflags: -stdlib=libc++, + skip_test: true, + tsan: true, + } + steps: - uses: actions/checkout@v2 - name: Install LLVM run: sudo apt-get install libllvm10 llvm-10 llvm-10-dev + - name: Install LLVM OpenMP runtime + run: sudo apt-get install libomp-10-dev libomp5-10 + - name: Install Clang run: sudo apt-get install clang-10 clang-tidy-10 + - name: Install libc++ + if: contains(matrix.config.cxxflags, '-stdlib=libc++') + run: sudo apt-get install --no-install-recommends libc++-10-dev libc++abi-10-dev + - name: Install OpenMPI run: sudo apt-get install libopenmpi-dev openmpi-bin - name: Install lcov + if: matrix.config.coverage run: sudo apt-get install lcov - name: Setup env @@ -36,53 +118,64 @@ jobs: sudo ln -f -s /usr/bin/FileCheck-10 /usr/bin/FileCheck sudo ln -f -s /usr/bin/llc-10 /usr/bin/llc sudo ln -f -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy - echo "EXTERNAL_LIT=/usr/lib/llvm-10/build/utils/lit/lit.py" >> $GITHUB_ENV - name: Configure TypeART run: | cmake -B build \ - -DTEST_CONFIG=ON \ - -DENABLE_CODE_COVERAGE=ON \ - -DSOFTCOUNTERS=ON \ - -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} + -DTEST_CONFIG=ON -DSOFTCOUNTERS=ON \ + -DENABLE_CODE_COVERAGE=${{ matrix.config.coverage }} \ + -DENABLE_TSAN=${{ matrix.config.tsan }} \ + -DENABLE_ASAN=${{ matrix.config.tsan == false }} \ + -DENABLE_UBSAN=${{ matrix.config.tsan == false }} \ + -DENABLE_SAFEPTR=${{ matrix.config.safe_ptr }} \ + -DDISABLE_THREAD_SAFETY=${{ matrix.config.thread_unsafe }} \ + -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} \ + -DCMAKE_CXX_FLAGS="${{ matrix.config.cxxflags }}" \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} - name: Build TypeART run: cmake --build build --parallel 2 - - name: Test TypeART with coverage - run: | - cmake --build build --target lcov-clean - cmake --build build --target test -- ARGS=-VV + - name: Prepare TypeART coverage + if: matrix.config.coverage + run: cmake --build build --target lcov-clean + + - name: Test TypeART lit-suite + if: matrix.config.skip_test == false + run: cmake --build build --target lit-pass-test - name: Build coverage report + if: matrix.config.coverage run: cmake --build build --target lcov-html - - name: Build TypeART release + - name: Prepare coverage artifact + if: matrix.config.coverage run: | - cmake -B build_lulesh -DCMAKE_BUILD_TYPE=Release -DMPI_INTERCEPT_LIB=ON -DSHOW_STATS=ON -DSOFTCOUNTERS=ON - cmake --build build_lulesh --parallel + mkdir -p artifact/${{ matrix.config.name }} + mv build/profiles/ artifact/${{ matrix.config.name }} - - name: Test TypeART release on lulesh - working-directory: build_lulesh - run: ctest -V -R lulesh -O lulesh2.0_build.log - - - name: Prepare artifact - run: | - mkdir -p artifact/lulesh - mkdir -p artifact/coverage - mv build_lulesh/lulesh2.0_build.log artifact/lulesh/ - mv test/lulesh/lulesh2.0_out.log artifact/lulesh/ - mv test/lulesh/types.yaml artifact/lulesh/lulesh2.0_types.yaml - mv build/profiles/ artifact/coverage - - - name: Upload lulesh test artifact + - name: Upload test coverage artifact + if: matrix.config.coverage uses: actions/upload-artifact@v2 with: - name: typeart-ci + name: typeart-ci-coverage path: artifact - - name: Coveralls + - name: Coveralls (parallel) + if: matrix.config.coverage uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: build/typeart.coverage + flag-name: ${{ matrix.config.name }} + parallel: true + + finish-coverage: + needs: lit-suite + runs-on: ubuntu-20.04 + steps: + - name: Coveralls Finished + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/ext-ci.yml b/.github/workflows/ext-ci.yml index 2f9b86f0..143bfe76 100644 --- a/.github/workflows/ext-ci.yml +++ b/.github/workflows/ext-ci.yml @@ -8,11 +8,31 @@ on: env: CXX: clang++-10 CC: clang-10 + EXTERNAL_LIT: /usr/lib/llvm-10/build/utils/lit/lit.py jobs: - build-and-run-testbench: + run-testbench: runs-on: ubuntu-20.04 - if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[ci ext skip]')" + if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + fail-fast: false + matrix: + config: + - { + name: "Thread-safe-safeptr", + thread-safety: true, + safe-ptr: true, + } + - { + name: "Thread-safe", + thread-safety: true, + safe-ptr: false, + } + - { + name: "Thread-unsafe", + thread-safety: false, + safe-ptr: false, + } steps: - uses: actions/checkout@v2 @@ -23,14 +43,6 @@ jobs: ssh-key: ${{ secrets.AUTH_SSH_CI_EXT }} path: test-bench - - name: Checkout AD test-bench - uses: actions/checkout@v2 - with: - repository: ahueck/typeart-ad-benchmarks - ssh-key: ${{ secrets.AUTH_SSH_CI_EXT_AD }} - ref: feat/ci - path: ad-test-bench - - name: Install LLVM run: sudo apt-get install libllvm10 llvm-10 llvm-10-dev @@ -47,7 +59,6 @@ jobs: sudo ln -f -s /usr/bin/opt-10 /usr/bin/opt sudo ln -f -s /usr/bin/llc-10 /usr/bin/llc sudo ln -f -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy - echo "EXTERNAL_LIT=/usr/lib/llvm-10/build/utils/lit/lit.py" >> $GITHUB_ENV - name: Configure TypeART run: | @@ -55,9 +66,11 @@ jobs: -DMPI_INTERCEPT_LIB=ON \ -DSHOW_STATS=ON \ -DSOFTCOUNTERS=ON \ - -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} + -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} \ + -DENABLE_SAFEPTR=${{ matrix.config.safe-ptr }} \ + -DDISABLE_THREAD_SAFETY=${{ matrix.config.thread-safety }} - - name: Build & install + - name: Build & install TypeART run: | cmake --build build --parallel 2 --target install echo "TYPEART_PATH=${GITHUB_WORKSPACE}/install/typeart" >> $GITHUB_ENV @@ -82,6 +95,78 @@ jobs: working-directory: test-bench/build run: ctest -V -R amg2013 -O amg2013_build.log + - name: Prepare artifact + run: | + mkdir -p artifact/bench + mv test-bench/build/*_build.log artifact/bench + mv test-bench/artifact/* artifact/bench + + - name: Upload test-bench artifact + uses: actions/upload-artifact@v2 + with: + name: typeart-ci-ext + path: artifact + + run-AD-testbench: + runs-on: ubuntu-20.04 + if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + fail-fast: false + matrix: + config: + - { + name: "Thread-safe", + thread-safety: true, + safe-ptr: false, + } + - { + name: "Thread-unsafe", + thread-safety: false, + safe-ptr: false, + } + steps: + - uses: actions/checkout@v2 + + - name: Checkout AD test-bench + uses: actions/checkout@v2 + with: + repository: ahueck/typeart-ad-benchmarks + ssh-key: ${{ secrets.AUTH_SSH_CI_EXT_AD }} + ref: feat/ci + path: ad-test-bench + + - name: Install LLVM + run: sudo apt-get install libllvm10 llvm-10 llvm-10-dev + + - name: Install Clang + run: sudo apt-get install clang-10 clang-tidy-10 + + - name: Install OpenMPI + run: sudo apt-get install libopenmpi-dev openmpi-bin + + - name: Setup env + run: | + sudo ln -f -s /usr/bin/clang-10 /usr/bin/clang + sudo ln -f -s /usr/bin/clang++-10 /usr/bin/clang++ + sudo ln -f -s /usr/bin/opt-10 /usr/bin/opt + sudo ln -f -s /usr/bin/llc-10 /usr/bin/llc + sudo ln -f -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy + + - name: Configure TypeART + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release \ + -DMPI_INTERCEPT_LIB=ON \ + -DSHOW_STATS=ON \ + -DSOFTCOUNTERS=ON \ + -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} \ + -DENABLE_SAFEPTR=${{ matrix.config.safe-ptr }} \ + -DDISABLE_THREAD_SAFETY=${{ matrix.config.thread-safety }} + + - name: Build & install TypeART + run: | + cmake --build build --parallel 2 --target install + echo "TYPEART_PATH=${GITHUB_WORKSPACE}/install/typeart" >> $GITHUB_ENV + - name: Setup AD tests working-directory: ad-test-bench run: cmake -B build -DLOG_PATH=${GITHUB_WORKSPACE}/ad-test-bench/artifact @@ -92,17 +177,103 @@ jobs: - name: Prepare artifact run: | - mkdir -p artifact/bench mkdir -p artifact/ad-bench - mv test-bench/build/*_build.log artifact/bench - mv test-bench/artifact/* artifact/bench mv ad-test-bench/build/*_build.log artifact/ad-bench mv ad-test-bench/artifact/* artifact/ad-bench - - name: Upload test-bench artifact + - name: Upload AD test-bench artifact uses: actions/upload-artifact@v2 with: - name: typeart-ci-ext + name: typeart-ci-ext-ad path: artifact - + run-OMP-testbench: + runs-on: ubuntu-20.04 + if: "!contains(github.event.head_commit.message, '[ci skip]')" + + env: + OMP_NUM_THREAD: 2 + + strategy: + fail-fast: false + matrix: + config: + - { + name: "Thread-safe-safeptr", + thread-safety: true, + safe-ptr: true, + } + - { + name: "Thread-safe", + thread-safety: true, + safe-ptr: false, + } + steps: + - uses: actions/checkout@v2 + + - name: Checkout OMP test-bench + uses: actions/checkout@v2 + with: + repository: tudasc/typeart-bench + ssh-key: ${{ secrets.AUTH_SSH_CI_EXT }} + ref: ci/omp + path: omp-test-bench + + - name: Install LLVM + run: sudo apt-get install libllvm10 llvm-10 llvm-10-dev + + - name: Install Clang + run: sudo apt-get install clang-10 clang-tidy-10 + + - name: Install OpenMPI + run: sudo apt-get install libopenmpi-dev openmpi-bin + + - name: Install LLVM OpenMP runtime + run: sudo apt-get install libomp-10-dev libomp5-10 + + - name: Setup env + run: | + sudo ln -f -s /usr/bin/clang-10 /usr/bin/clang + sudo ln -f -s /usr/bin/clang++-10 /usr/bin/clang++ + sudo ln -f -s /usr/bin/opt-10 /usr/bin/opt + sudo ln -f -s /usr/bin/llc-10 /usr/bin/llc + sudo ln -f -s /usr/bin/clang-tidy-10 /usr/bin/clang-tidy + + - name: Configure TypeART + run: | + cmake -B build -DCMAKE_BUILD_TYPE=Release \ + -DMPI_INTERCEPT_LIB=ON \ + -DSHOW_STATS=ON \ + -DSOFTCOUNTERS=ON \ + -DLLVM_EXTERNAL_LIT=${EXTERNAL_LIT} \ + -DENABLE_SAFEPTR=${{ matrix.config.safe-ptr }} \ + -DDISABLE_THREAD_SAFETY=${{ matrix.config.thread-safety }} + + - name: Build & install TypeART + run: | + cmake --build build --parallel 2 --target install + echo "TYPEART_PATH=${GITHUB_WORKSPACE}/install/typeart" >> $GITHUB_ENV + + - name: Setup tests + working-directory: omp-test-bench + run: cmake -B build -DLOG_PATH=${GITHUB_WORKSPACE}/omp-test-bench/artifact + + - name: Run lulesh + working-directory: omp-test-bench/build + run: ctest -V -R lulesh -O lulesh2.0_build.log + + - name: Run amg2013 + working-directory: omp-test-bench/build + run: ctest -V -R amg2013 -O amg2013_build.log + + - name: Prepare artifact + run: | + mkdir -p artifact/bench + mv omp-test-bench/build/*_build.log artifact/bench + mv omp-test-bench/artifact/* artifact/bench + + - name: Upload omp-test-bench artifact + uses: actions/upload-artifact@v2 + with: + name: typeart-ci-ext-omp + path: artifact diff --git a/CMakeLists.txt b/CMakeLists.txt index f816ec72..12e24aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ add_format_target(format-sources lib/typelib/*.h lib/support/*.cpp lib/support/*.h + demo/*.c + demo/*.h ) add_subdirectory(externals) diff --git a/cmake/ToolchainOptions.cmake b/cmake/ToolchainOptions.cmake index 2e4fe180..9e24adbb 100644 --- a/cmake/ToolchainOptions.cmake +++ b/cmake/ToolchainOptions.cmake @@ -25,6 +25,8 @@ mark_as_advanced(TEST_CONFIGURE_IDE) option(ENABLE_TSAN "Build runtime lib and tests with fsanitize=thread" OFF) option(ENABLE_SAFEPTR "Use external safe_ptr map wrapper instead of mutex" OFF) cmake_dependent_option(DISABLE_THREAD_SAFETY "Explicitly make runtime *not* thread-safe." OFF "NOT ENABLE_SAFEPTR" OFF) +cmake_dependent_option(ENABLE_ASAN "Build runtime lib and tests with fsanitize=address." OFF "NOT ENABLE_TSAN" OFF) +cmake_dependent_option(ENABLE_UBSAN "Build runtime lib and tests with fsanitize=undefined." OFF "NOT ENABLE_TSAN" OFF) include(AddLLVM) include(llvm-lit) @@ -33,6 +35,8 @@ include(clang-format) include(llvm-util) include(log-util) include(coverage) +include(sanitizer-targets) +include(target-util) if (TEST_CONFIG) set(LOG_LEVEL 2 CACHE STRING "" FORCE) @@ -54,42 +58,3 @@ if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${typeart_SOURCE_DIR}/install/typeart" CACHE PATH "Default install path" FORCE) message(STATUS "Installing to (default): ${CMAKE_INSTALL_PREFIX}") endif () - -function(target_project_compile_options target) - cmake_parse_arguments(ARG "" "" "PRIVATE_FLAGS;PUBLIC_FLAGS" ${ARGN}) - - target_compile_options(${target} PRIVATE - -Wall -Wextra -pedantic - -Wunreachable-code -Wwrite-strings - -Wpointer-arith -Wcast-align - -Wcast-qual -Wno-unused-parameter - ) - - if (ARG_PRIVATE_FLAGS) - target_compile_options(${target} PRIVATE - "${ARG_PRIVATE_FLAGS}" - ) - endif () - - if (ARG_PUBLIC_FLAGS) - target_compile_options(${target} PUBLIC - "${ARG_PUBLIC_FLAGS}" - ) - endif () -endfunction() - -function(target_project_compile_definitions target) - cmake_parse_arguments(ARG "" "" "PRIVATE_DEFS;PUBLIC_DEFS" ${ARGN}) - - if (ARG_PRIVATE_DEFS) - target_compile_definitions(${target} PRIVATE - "${ARG_PRIVATE_DEFS}" - ) - endif () - - if (ARG_PUBLIC_DEFS) - target_compile_definitions(${target} PUBLIC - "${ARG_PUBLIC_DEFS}" - ) - endif () -endfunction() diff --git a/cmake/modules/sanitizer-targets.cmake b/cmake/modules/sanitizer-targets.cmake new file mode 100644 index 00000000..2e3ca079 --- /dev/null +++ b/cmake/modules/sanitizer-targets.cmake @@ -0,0 +1,58 @@ +function(target_sanitizer_options target) + cmake_parse_arguments(ARG "" "" "SAN_FLAGS;LINK_FLAGS" ${ARGN}) + #target_compile_options(typeart-rt PRIVATE -fsanitize=address,undefined -fno-sanitize=vptr,function -fno-omit-frame-pointer) + #target_link_options(typeart-rt PRIVATE -fsanitize=address,undefined -fno-omit-frame-pointer) + target_compile_options(${target} + PRIVATE + ${ARG_SAN_FLAGS} + ) + + target_link_options(${target} + PUBLIC + ${ARG_SAN_FLAGS} + ) + + if (ARG_LINK_FLAGS) + target_link_options(${target} + PUBLIC + "${ARG_LINK_FLAGS}" + ) + endif() + +endfunction() + +function(target_tsan_flags flags) + set(${flags} -fsanitize=thread PARENT_SCOPE) +endfunction() + +function(target_asan_flags flags) + set(${flags} -fsanitize=address -fno-omit-frame-pointer PARENT_SCOPE) +endfunction() + +function(target_ubsan_flags flags) + set(${flags} -fsanitize=undefined -fno-sanitize=vptr,function -fno-sanitize-recover=undefined,integer PARENT_SCOPE) +endfunction() + +function(target_asan_options target) + target_asan_flags(asan_f) + target_sanitizer_options(${target} + SAN_FLAGS + ${asan_f} + ) +endfunction() + +function(target_ubsan_options target) + target_ubsan_flags(ubsan_f) + target_sanitizer_options(${target} + SAN_FLAGS + ${ubsan_f} + ) +endfunction() + +function(target_tsan_options target) + target_tsan_flags(tsan_f) + target_sanitizer_options(${target} + SAN_FLAGS + "${tsan_f}" + ) +endfunction() \ No newline at end of file diff --git a/cmake/modules/target-util.cmake b/cmake/modules/target-util.cmake new file mode 100644 index 00000000..e962d74c --- /dev/null +++ b/cmake/modules/target-util.cmake @@ -0,0 +1,38 @@ +function(target_project_compile_options target) + cmake_parse_arguments(ARG "" "" "PRIVATE_FLAGS;PUBLIC_FLAGS" ${ARGN}) + + target_compile_options(${target} PRIVATE + -Wall -Wextra -pedantic + -Wunreachable-code -Wwrite-strings + -Wpointer-arith -Wcast-align + -Wcast-qual -Wno-unused-parameter + ) + + if (ARG_PRIVATE_FLAGS) + target_compile_options(${target} PRIVATE + "${ARG_PRIVATE_FLAGS}" + ) + endif () + + if (ARG_PUBLIC_FLAGS) + target_compile_options(${target} PUBLIC + "${ARG_PUBLIC_FLAGS}" + ) + endif () +endfunction() + +function(target_project_compile_definitions target) + cmake_parse_arguments(ARG "" "" "PRIVATE_DEFS;PUBLIC_DEFS" ${ARGN}) + + if (ARG_PRIVATE_DEFS) + target_compile_definitions(${target} PRIVATE + "${ARG_PRIVATE_DEFS}" + ) + endif () + + if (ARG_PUBLIC_DEFS) + target_compile_definitions(${target} PUBLIC + "${ARG_PUBLIC_DEFS}" + ) + endif () +endfunction() \ No newline at end of file diff --git a/demo/01_struct_example.c b/demo/01_struct_example.c index 916af4af..cb2ef20d 100644 --- a/demo/01_struct_example.c +++ b/demo/01_struct_example.c @@ -39,7 +39,7 @@ void printParticles(struct particle* p, int count, int rank) { } int main(int argc, char** argv) { - int size = -1; + int size = -1; int my_rank = -1, i, j; int array_of_blocklengths[COUNT] = {1, 3, 3, 1, 1}; @@ -47,7 +47,7 @@ int main(int argc, char** argv) { #ifdef USE_STACK struct particle localParticles[COUNT], remoteParticles[COUNT]; #else - struct particle* localParticles = malloc(sizeof(struct particle) * COUNT); + struct particle* localParticles = malloc(sizeof(struct particle) * COUNT); struct particle* remoteParticles = malloc(sizeof(struct particle) * COUNT); #endif diff --git a/demo/02_broken_struct_example.c b/demo/02_broken_struct_example.c index 4f095248..4f64a157 100644 --- a/demo/02_broken_struct_example.c +++ b/demo/02_broken_struct_example.c @@ -39,7 +39,7 @@ void printParticles(struct particle* p, int count, int rank) { } int main(int argc, char** argv) { - int size = -1; + int size = -1; int my_rank = -1, i, j; int array_of_blocklengths[COUNT] = {1, 1, 3, 3, 1}; @@ -47,7 +47,7 @@ int main(int argc, char** argv) { #ifdef USE_STACK struct particle localParticles[COUNT], remoteParticles[COUNT]; #else - struct particle* localParticles = malloc(sizeof(struct particle) * COUNT); + struct particle* localParticles = malloc(sizeof(struct particle) * COUNT); struct particle* remoteParticles = malloc(sizeof(struct particle) * COUNT); #endif diff --git a/demo/tool.c b/demo/tool.c index c1877abf..eda049dd 100644 --- a/demo/tool.c +++ b/demo/tool.c @@ -1,8 +1,7 @@ +#include #include #include -#include - int isCompatible(MPI_Datatype mpi_type, typeart_builtin_type recorded_type) { // This comparison is not exhaustive and is only used for this simple demo switch (recorded_type) { @@ -60,8 +59,8 @@ void analyseBuffer(const void* buf, int count, MPI_Datatype type) { } else { const char* recorded_name = typeart_get_type_name(type_id); - fprintf(stdout, "Error: Incompatible buffer of type %d (%s) - expected %s instead\n", type_id, - recorded_name, type_name); + fprintf(stdout, "Error: Incompatible buffer of type %d (%s) - expected %s instead\n", type_id, recorded_name, + type_name); } } else { @@ -118,16 +117,14 @@ int MPI_Sendrecv(const void* sendbuf, int sendcount, MPI_Datatype sendtype, int int MPI_Bcast(void* buf, int sendcount, MPI_Datatype sendtype, int root, MPI_Comm comm) { int rank; MPI_Comm_rank(comm, &rank); - if( rank == root ) { + if (rank == root) { printf("Analyze Send\n"); analyseBuffer(buf, sendcount, sendtype); -// analyseBuffer(0, sendcount, sendtype); + // analyseBuffer(0, sendcount, sendtype); } else { printf("Analyze Recv\n"); analyseBuffer(buf, sendcount, sendtype); -// analyseBuffer(0, recvcount, recvtype); + // analyseBuffer(0, recvcount, recvtype); } return PMPI_Bcast(buf, sendcount, sendtype, root, comm); } - - diff --git a/demo/toy.c b/demo/toy.c index 443c53c3..7c951790 100644 --- a/demo/toy.c +++ b/demo/toy.c @@ -1,9 +1,9 @@ #include +#include #include #include -#include -struct test{ +struct test { int a; double b; unsigned int c; @@ -12,12 +12,11 @@ struct test{ struct test* f; }; - -int main(int argc, char** argv){ +int main(int argc, char** argv) { MPI_Init(&argc, &argv); #ifdef NOSTACK - struct test * mystruct=malloc(sizeof(struct test)*5); + struct test* mystruct = malloc(sizeof(struct test) * 5); #else struct test mystruct[5]; #endif @@ -25,64 +24,77 @@ int main(int argc, char** argv){ int type; typeart_builtin_type btype; size_t count; - + #ifdef NOSTACK - int* buffer = malloc(sizeof(int)*50); + int* buffer = malloc(sizeof(int) * 50); #else int buffer[50]; #endif typeart_status status = typeart_get_type(mystruct, &type, &count); - - if (status==TA_OK) printf("type (id=%i), count=%lu\n", type, count); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("type (id=%i), count=%lu\n", type, count); + else + printf("error: %i\n", status); + status = typeart_get_builtin_type(&(mystruct[2].e), &btype); - - if (status==TA_OK) printf("type (kind=%i)\n", btype); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("type (kind=%i)\n", btype); + else + printf("error: %i\n", status); + status = typeart_get_type(&(mystruct[2].e), &type, &count); - - if (status==TA_OK) printf("type (id=%i), count=%lu\n", type, count); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("type (id=%i), count=%lu\n", type, count); + else + printf("error: %i\n", status); + status = typeart_get_builtin_type(&(mystruct[2].c), &btype); - - if (status==TA_OK) printf("type (kind=%i)\n", btype); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("type (kind=%i)\n", btype); + else + printf("error: %i\n", status); + status = typeart_get_type(&(mystruct[2].c), &type, &count); - - if (status==TA_OK) printf("type (id=%i), count=%lu\n", type, count); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("type (id=%i), count=%lu\n", type, count); + else + printf("error: %i\n", status); + const void* base_address; size_t offset; status = typeart_get_containing_type(&(mystruct[2].c), &type, &count, &base_address, &offset); - - if (status==TA_OK) printf("containing_type (id=%i), count=%lu, %p, %lu\n", type, count, base_address, offset); - else printf("error: %i\n", status); - + + if (status == TA_OK) + printf("containing_type (id=%i), count=%lu, %p, %lu\n", type, count, base_address, offset); + else + printf("error: %i\n", status); + printf("buffer\n"); - + status = typeart_get_containing_type(&(buffer[20]), &type, &count, &base_address, &offset); - - if (status==TA_OK) printf("containing_type (id=%i), count=%lu, %p, %lu\n", type, count, base_address, offset); - else printf("error: %i\n", status); - - MPI_Sendrecv(mystruct, 1, MPI_INT, 0, 0, buffer+20, 1, MPI_INT, - 0,0, MPI_COMM_SELF, MPI_STATUS_IGNORE); + + if (status == TA_OK) + printf("containing_type (id=%i), count=%lu, %p, %lu\n", type, count, base_address, offset); + else + printf("error: %i\n", status); + + MPI_Sendrecv(mystruct, 1, MPI_INT, 0, 0, buffer + 20, 1, MPI_INT, 0, 0, MPI_COMM_SELF, MPI_STATUS_IGNORE); MPI_Finalize(); #ifdef NOSTACK - free(mystruct); + free(mystruct); #else #endif #ifdef NOSTACK - free(buffer); + free(buffer); #else #endif } diff --git a/lib/passes/TypeARTPass.cpp b/lib/passes/TypeARTPass.cpp index abed1d9c..47a2b3bd 100644 --- a/lib/passes/TypeARTPass.cpp +++ b/lib/passes/TypeARTPass.cpp @@ -1,22 +1,36 @@ #include "TypeARTPass.h" -//#include "RuntimeInterface.h" #include "analysis/MemInstFinderPass.h" #include "instrumentation/MemOpArgCollector.h" #include "instrumentation/MemOpInstrumentation.h" #include "instrumentation/TypeARTFunctions.h" #include "support/Logger.h" #include "support/Table.h" -#include "typelib/TypeIO.h" +#include "typelib/TypeDB.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/IR/Instructions.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/PassAnalysisSupport.h" +#include "llvm/PassSupport.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Format.h" -#include "llvm/Transforms/Utils/CtorUtils.h" +#include "llvm/Support/raw_ostream.h" +#include +#include #include +#include + +namespace llvm { +class BasicBlock; +} // namespace llvm using namespace llvm; diff --git a/lib/passes/TypeARTPass.h b/lib/passes/TypeARTPass.h index 017a8b09..76eab256 100644 --- a/lib/passes/TypeARTPass.h +++ b/lib/passes/TypeARTPass.h @@ -5,10 +5,10 @@ #include "instrumentation/Instrumentation.h" #include "instrumentation/InstrumentationHelper.h" #include "instrumentation/TypeARTFunctions.h" -#include "typelib/TypeDB.h" #include "llvm/Pass.h" +#include #include namespace llvm { @@ -16,6 +16,8 @@ class Constant; class Module; class Function; class AnalysisUsage; +class Value; +class raw_ostream; } // namespace llvm namespace typeart::pass { diff --git a/lib/passes/TypeManager.cpp b/lib/passes/TypeManager.cpp index 43dff118..b41f5bcd 100644 --- a/lib/passes/TypeManager.cpp +++ b/lib/passes/TypeManager.cpp @@ -10,8 +10,20 @@ #include "typelib/TypeIO.h" #include "typelib/TypeInterface.h" -#include +#include "llvm/ADT/None.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/TypeSize.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include #include +#include namespace typeart { diff --git a/lib/passes/TypeManager.h b/lib/passes/TypeManager.h index cbd02d68..919bc639 100644 --- a/lib/passes/TypeManager.h +++ b/lib/passes/TypeManager.h @@ -3,9 +3,17 @@ #include "typelib/TypeDB.h" -#include -#include -#include +#include "llvm/ADT/StringMap.h" + +#include +#include + +namespace llvm { +class DataLayout; +class StructType; +class Type; +class VectorType; +} // namespace llvm namespace typeart { diff --git a/lib/passes/analysis/MemInstFinderPass.cpp b/lib/passes/analysis/MemInstFinderPass.cpp index 9f3ca770..83969dca 100644 --- a/lib/passes/analysis/MemInstFinderPass.cpp +++ b/lib/passes/analysis/MemInstFinderPass.cpp @@ -7,10 +7,11 @@ #include "MemInstFinderPass.h" -#include "MemOpVisitor.h" +#include "analysis/MemOpData.h" #include "filter/CGForwardFilter.h" #include "filter/CGInterface.h" #include "filter/Filter.h" +#include "filter/Matcher.h" #include "filter/StandardFilter.h" #include "filter/StdForwardFilter.h" #include "support/Logger.h" @@ -18,10 +19,28 @@ #include "support/TypeUtil.h" #include "support/Util.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/PassAnalysisSupport.h" +#include "llvm/PassSupport.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include using namespace llvm; diff --git a/lib/passes/analysis/MemInstFinderPass.h b/lib/passes/analysis/MemInstFinderPass.h index 14b998ab..80ce3ce4 100644 --- a/lib/passes/analysis/MemInstFinderPass.h +++ b/lib/passes/analysis/MemInstFinderPass.h @@ -11,9 +11,11 @@ #include "MemOpData.h" #include "MemOpVisitor.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Pass.h" #include +#include namespace llvm { class Module; @@ -21,6 +23,8 @@ class Function; class AllocaInst; class CallSite; class GlobalValue; +class AnalysisUsage; +class raw_ostream; } // namespace llvm namespace typeart { diff --git a/lib/passes/analysis/MemOpVisitor.cpp b/lib/passes/analysis/MemOpVisitor.cpp index fd154936..e0393b3f 100644 --- a/lib/passes/analysis/MemOpVisitor.cpp +++ b/lib/passes/analysis/MemOpVisitor.cpp @@ -7,11 +7,25 @@ #include "MemOpVisitor.h" +#include "analysis/MemOpData.h" #include "support/Logger.h" #include "support/TypeUtil.h" -#include "support/Util.h" -#include +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" + +#include namespace typeart::finder { diff --git a/lib/passes/analysis/MemOpVisitor.h b/lib/passes/analysis/MemOpVisitor.h index b9d7af07..d68f93cd 100644 --- a/lib/passes/analysis/MemOpVisitor.h +++ b/lib/passes/analysis/MemOpVisitor.h @@ -13,6 +13,12 @@ #include "llvm/ADT/StringMap.h" #include "llvm/IR/InstVisitor.h" +namespace llvm { +class AllocaInst; +class CallBase; +class Module; +} // namespace llvm + namespace typeart::finder { struct MemOpVisitor : public llvm::InstVisitor { diff --git a/lib/passes/filter/CGForwardFilter.cpp b/lib/passes/filter/CGForwardFilter.cpp index 62494260..1950f976 100644 --- a/lib/passes/filter/CGForwardFilter.cpp +++ b/lib/passes/filter/CGForwardFilter.cpp @@ -7,6 +7,24 @@ #include "CGInterface.h" #include "Matcher.h" #include "OmpUtil.h" +#include "filter/FilterBase.h" +#include "filter/FilterUtil.h" +#include "support/Logger.h" +#include "support/Util.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" + +#include + +namespace llvm { +class Function; +} // namespace llvm namespace typeart::filter { diff --git a/lib/passes/filter/CGForwardFilter.h b/lib/passes/filter/CGForwardFilter.h index 23b3d69a..a602c8ce 100644 --- a/lib/passes/filter/CGForwardFilter.h +++ b/lib/passes/filter/CGForwardFilter.h @@ -7,6 +7,26 @@ #include "FilterBase.h" #include "Matcher.h" +#include "filter/CGInterface.h" +#include "filter/IRPath.h" + +#include "llvm/IR/CallSite.h" + +#include +#include + +namespace llvm { +class Function; +class Value; +} // namespace llvm +namespace typeart { +namespace filter { +namespace omp { +struct OmpContext; +} // namespace omp +struct DefaultSearch; +} // namespace filter +} // namespace typeart namespace typeart::filter { diff --git a/lib/passes/filter/CGInterface.cpp b/lib/passes/filter/CGInterface.cpp index a2562548..89a044fc 100644 --- a/lib/passes/filter/CGInterface.cpp +++ b/lib/passes/filter/CGInterface.cpp @@ -3,8 +3,16 @@ #include "support/Logger.h" #include "support/Util.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include namespace typeart::filter { diff --git a/lib/passes/filter/CGInterface.h b/lib/passes/filter/CGInterface.h index a463f013..597037f4 100644 --- a/lib/passes/filter/CGInterface.h +++ b/lib/passes/filter/CGInterface.h @@ -3,9 +3,12 @@ #include "llvm/Support/JSON.h" +#include +#include #include #include #include +#include namespace typeart::filter { diff --git a/lib/passes/filter/FilterUtil.cpp b/lib/passes/filter/FilterUtil.cpp index 17573bda..ed0bad60 100644 --- a/lib/passes/filter/FilterUtil.cpp +++ b/lib/passes/filter/FilterUtil.cpp @@ -4,6 +4,10 @@ #include "FilterUtil.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Support/raw_ostream.h" + namespace typeart::filter { void FunctionAnalysis::clear() { diff --git a/lib/passes/filter/FilterUtil.h b/lib/passes/filter/FilterUtil.h index e0b84635..6e32b7d6 100644 --- a/lib/passes/filter/FilterUtil.h +++ b/lib/passes/filter/FilterUtil.h @@ -7,13 +7,34 @@ #include "IRPath.h" #include "OmpUtil.h" +#include "support/DefUseChain.h" #include "support/Logger.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/IR/Argument.h" #include "llvm/IR/CallSite.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Use.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include + +namespace llvm { +class Value; +class raw_ostream; +} // namespace llvm + using namespace llvm; namespace typeart::filter { diff --git a/lib/passes/filter/IRPath.h b/lib/passes/filter/IRPath.h index f35d602a..502ce0dc 100644 --- a/lib/passes/filter/IRPath.h +++ b/lib/passes/filter/IRPath.h @@ -12,7 +12,9 @@ #include "llvm/IR/Value.h" #include "llvm/Support/raw_ostream.h" +#include #include + namespace typeart::filter { struct IRPath { diff --git a/lib/passes/filter/Matcher.h b/lib/passes/filter/Matcher.h index 97e07683..338e0646 100644 --- a/lib/passes/filter/Matcher.h +++ b/lib/passes/filter/Matcher.h @@ -67,18 +67,22 @@ class FunctionOracleMatcher final : public Matcher { const auto f = c.getCalledFunction(); if (f != nullptr) { const auto f_name = util::demangle(f->getName()); + StringRef f_name_ref{f_name}; if (continue_set.count(f_name) > 0) { return MatchResult::ShouldContinue; } if (skip_set.count(f_name) > 0) { return MatchResult::ShouldSkip; } - if (StringRef(f_name).startswith("__typeart_")) { + if (f_name_ref.startswith("__typeart_")) { return MatchResult::ShouldSkip; } if (mem_operations.kind(f_name)) { return MatchResult::ShouldSkip; } + if (f_name_ref.startswith("__ubsan") || f_name_ref.startswith("__asan") || f_name_ref.startswith("__msan")) { + return MatchResult::ShouldContinue; + } } return MatchResult::NoMatch; } diff --git a/lib/passes/filter/StandardFilter.cpp b/lib/passes/filter/StandardFilter.cpp index e8ae2962..b884869a 100644 --- a/lib/passes/filter/StandardFilter.cpp +++ b/lib/passes/filter/StandardFilter.cpp @@ -4,6 +4,28 @@ #include "StandardFilter.h" +#include "support/Logger.h" +#include "support/Util.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Argument.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Use.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + namespace typeart::filter::deprecated { StandardFilter::StandardFilter(const std::string& glob, bool CallFilterDeep) diff --git a/lib/passes/filter/StandardFilter.h b/lib/passes/filter/StandardFilter.h index b64c481f..83a7131d 100644 --- a/lib/passes/filter/StandardFilter.h +++ b/lib/passes/filter/StandardFilter.h @@ -16,6 +16,14 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Format.h" +#include + +namespace llvm { +class Argument; +class Function; +class Value; +} // namespace llvm + namespace typeart::filter::deprecated { using namespace llvm; diff --git a/lib/passes/filter/StdForwardFilter.cpp b/lib/passes/filter/StdForwardFilter.cpp index 7a838aad..90d92dbe 100644 --- a/lib/passes/filter/StdForwardFilter.cpp +++ b/lib/passes/filter/StdForwardFilter.cpp @@ -5,6 +5,21 @@ #include "StdForwardFilter.h" #include "OmpUtil.h" +#include "filter/FilterBase.h" +#include "filter/FilterUtil.h" +#include "filter/Matcher.h" +#include "support/Logger.h" + +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" + +#include + +namespace llvm { +class Function; +} // namespace llvm namespace typeart::filter { diff --git a/lib/passes/filter/StdForwardFilter.h b/lib/passes/filter/StdForwardFilter.h index 509a9226..aa4df116 100644 --- a/lib/passes/filter/StdForwardFilter.h +++ b/lib/passes/filter/StdForwardFilter.h @@ -7,6 +7,24 @@ #include "FilterBase.h" #include "Matcher.h" +#include "filter/IRPath.h" + +#include "llvm/IR/CallSite.h" + +#include + +namespace llvm { +class Function; +class Value; +} // namespace llvm +namespace typeart { +namespace filter { +namespace omp { +struct OmpContext; +} // namespace omp +struct DefaultSearch; +} // namespace filter +} // namespace typeart namespace typeart::filter { diff --git a/lib/passes/instrumentation/Instrumentation.cpp b/lib/passes/instrumentation/Instrumentation.cpp index e628abff..95145c82 100644 --- a/lib/passes/instrumentation/Instrumentation.cpp +++ b/lib/passes/instrumentation/Instrumentation.cpp @@ -3,6 +3,8 @@ // #include "Instrumentation.h" +#include + namespace typeart { InstrumentationContext::InstrumentationContext(std::unique_ptr col, diff --git a/lib/passes/instrumentation/Instrumentation.h b/lib/passes/instrumentation/Instrumentation.h index 84b24e51..341c9840 100644 --- a/lib/passes/instrumentation/Instrumentation.h +++ b/lib/passes/instrumentation/Instrumentation.h @@ -5,12 +5,16 @@ #ifndef TYPEART_INSTRUMENTATION_H #define TYPEART_INSTRUMENTATION_H -#include "../analysis/MemOpData.h" +#include "analysis/MemOpData.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" +#include +#include + namespace llvm { class Value; } diff --git a/lib/passes/instrumentation/InstrumentationHelper.cpp b/lib/passes/instrumentation/InstrumentationHelper.cpp index 585d3d38..cd887c32 100644 --- a/lib/passes/instrumentation/InstrumentationHelper.cpp +++ b/lib/passes/instrumentation/InstrumentationHelper.cpp @@ -2,13 +2,16 @@ #include "support/Logger.h" -#include "llvm/IR/Argument.h" -#include "llvm/IR/CFG.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/GlobalValue.h" -#include "llvm/IR/LLVMContext.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" namespace typeart { diff --git a/lib/passes/instrumentation/InstrumentationHelper.h b/lib/passes/instrumentation/InstrumentationHelper.h index 75b3e7e4..eba8ad99 100644 --- a/lib/passes/instrumentation/InstrumentationHelper.h +++ b/lib/passes/instrumentation/InstrumentationHelper.h @@ -15,12 +15,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/IRBuilder.h" +#include #include #include #include namespace llvm { -class LLVMContext; class Function; class Module; class Value; diff --git a/lib/passes/instrumentation/MemOpArgCollector.cpp b/lib/passes/instrumentation/MemOpArgCollector.cpp index 331b7dd2..53ec2527 100644 --- a/lib/passes/instrumentation/MemOpArgCollector.cpp +++ b/lib/passes/instrumentation/MemOpArgCollector.cpp @@ -5,12 +5,26 @@ #include "MemOpArgCollector.h" #include "../TypeManager.h" +#include "Instrumentation.h" #include "InstrumentationHelper.h" #include "support/Logger.h" #include "support/TypeUtil.h" #include "support/Util.h" +#include "typelib/TypeInterface.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include + +namespace llvm { +class DataLayout; +class Value; +} // namespace llvm namespace tu = typeart::util::type; using namespace llvm; @@ -36,7 +50,7 @@ HeapArgList MemOpArgCollector::collectHeap(const MallocDataList& mallocs) { int typeId = type_m->getOrRegisterType(malloc_call->getType()->getPointerElementType(), dl); // retrieveTypeID(tu::getVoidType(c)); if (typeId == TA_UNKNOWN_TYPE) { - LOG_ERROR("Unknown allocated type. Not instrumenting. " << util::dump(*malloc_call)); + LOG_ERROR("Unknown heap type. Not instrumenting. " << util::dump(*malloc_call)); // TODO notify caller that we skipped: via lambda callback function continue; } @@ -65,7 +79,7 @@ HeapArgList MemOpArgCollector::collectHeap(const MallocDataList& mallocs) { continue; } } else { - LOG_ERROR("Primary bitcast is null. malloc: " << util::dump(*malloc_call)) + LOG_WARNING("Primary bitcast is null. malloc: " << util::dump(*malloc_call)) } auto* typeIdConst = instr_helper->getConstantFor(IType::type_id, typeId); @@ -169,7 +183,8 @@ StackArgList MemOpArgCollector::collectStack(const AllocaDataList& allocs) { int typeId = type_m->getOrRegisterType(elementType, dl); if (typeId == TA_UNKNOWN_TYPE) { - LOG_ERROR("Type is not supported: " << util::dump(*elementType)); + LOG_ERROR("Unknown stack type. Not instrumenting. " << util::dump(*elementType)); + continue; } auto* typeIdConst = instr_helper->getConstantFor(IType::type_id, typeId); @@ -200,7 +215,13 @@ GlobalArgList MemOpArgCollector::collectGlobal(const GlobalDataList& globals) { type = tu::getArrayElementType(type); } - int typeId = type_m->getOrRegisterType(type, dl); + int typeId = type_m->getOrRegisterType(type, dl); + + if (typeId == TA_UNKNOWN_TYPE) { + LOG_ERROR("Unknown global type. Not instrumenting. " << util::dump(*type)); + continue; + } + auto* typeIdConst = instr_helper->getConstantFor(IType::type_id, typeId); auto* numElementsConst = instr_helper->getConstantFor(IType::extent, numElements); // auto globalPtr = IRB.CreateBitOrPointerCast(global, instr.getTypeFor(IType::ptr)); diff --git a/lib/passes/instrumentation/MemOpArgCollector.h b/lib/passes/instrumentation/MemOpArgCollector.h index 1a2d127f..08d83c86 100644 --- a/lib/passes/instrumentation/MemOpArgCollector.h +++ b/lib/passes/instrumentation/MemOpArgCollector.h @@ -6,6 +6,7 @@ #define TYPEART_MEMOPARGCOLLECTOR_H #include "Instrumentation.h" +#include "analysis/MemOpData.h" namespace typeart { class TypeManager; diff --git a/lib/passes/instrumentation/MemOpInstrumentation.cpp b/lib/passes/instrumentation/MemOpInstrumentation.cpp index 895bc0b1..882bf9d2 100644 --- a/lib/passes/instrumentation/MemOpInstrumentation.cpp +++ b/lib/passes/instrumentation/MemOpInstrumentation.cpp @@ -4,19 +4,35 @@ #include "MemOpInstrumentation.h" -#include "../TypeManager.h" +#include "Instrumentation.h" #include "InstrumentationHelper.h" #include "TransformUtil.h" #include "TypeARTFunctions.h" +#include "analysis/MemOpData.h" #include "support/Logger.h" #include "support/OmpUtil.h" #include "support/Util.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" -#include "llvm/Transforms/Utils/CtorUtils.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include + +namespace llvm { +class Value; +} // namespace llvm + using namespace llvm; namespace typeart { diff --git a/lib/passes/instrumentation/TypeARTFunctions.cpp b/lib/passes/instrumentation/TypeARTFunctions.cpp index f100b5e6..7eadbb0b 100644 --- a/lib/passes/instrumentation/TypeARTFunctions.cpp +++ b/lib/passes/instrumentation/TypeARTFunctions.cpp @@ -6,12 +6,24 @@ #include "support/Logger.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/Argument.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalValue.h" -#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/raw_ostream.h" + +#include + +namespace typeart { +class InstrumentationHelper; +} // namespace typeart using namespace llvm; diff --git a/lib/passes/instrumentation/TypeARTFunctions.h b/lib/passes/instrumentation/TypeARTFunctions.h index 2be8bf93..df3fc9ae 100644 --- a/lib/passes/instrumentation/TypeARTFunctions.h +++ b/lib/passes/instrumentation/TypeARTFunctions.h @@ -11,6 +11,8 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include + namespace llvm { class Function; class Type; @@ -18,6 +20,7 @@ class Module; } // namespace llvm namespace typeart { +class InstrumentationHelper; enum class IFunc : unsigned { heap, diff --git a/lib/passes/support/DefUseChain.h b/lib/passes/support/DefUseChain.h index 7a6ee973..55b4a6f5 100644 --- a/lib/passes/support/DefUseChain.h +++ b/lib/passes/support/DefUseChain.h @@ -10,9 +10,10 @@ using namespace llvm; #include "support/Logger.h" #include "support/Util.h" +#include "llvm/IR/Instructions.h" + #include #include -#include namespace typeart::util { diff --git a/lib/passes/support/TypeUtil.cpp b/lib/passes/support/TypeUtil.cpp index 5732672b..6a0371a6 100644 --- a/lib/passes/support/TypeUtil.cpp +++ b/lib/passes/support/TypeUtil.cpp @@ -4,8 +4,13 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/TypeSize.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; diff --git a/lib/runtime/AccessCountPrinter.h b/lib/runtime/AccessCountPrinter.h index 8df124eb..5d484199 100644 --- a/lib/runtime/AccessCountPrinter.h +++ b/lib/runtime/AccessCountPrinter.h @@ -24,8 +24,7 @@ namespace memory { struct MemOverhead { static constexpr auto pointerMapSize = sizeof(RuntimeT::PointerMap); // Map overhead static constexpr auto perNodeSizeMap = - sizeof(std::remove_pointer::iterator::_Link_type>::type) + - sizeof(RuntimeT::MapEntry); // not applicable to btree + 64U + sizeof(RuntimeT::MapEntry); // rough estimate, not applicable to btree; 64U is internal node size static constexpr auto stackVectorSize = sizeof(RuntimeT::Stack); // Stack overhead static constexpr auto perNodeSizeStack = sizeof(RuntimeT::StackEntry); // Stack allocs double stack{0}; diff --git a/lib/runtime/AccessCounter.h b/lib/runtime/AccessCounter.h index 0b0e2826..eb19cad6 100644 --- a/lib/runtime/AccessCounter.h +++ b/lib/runtime/AccessCounter.h @@ -45,7 +45,18 @@ inline void updateMax(std::atomic& maxVal, T newVal) noexcept { } struct CounterStats { + private: + CounterStats(double sum, double min, double max, double mean, double std) + : sum(sum), minVal(min), maxVal(max), meanVal(mean), stdVal(std) { + } + + CounterStats() = default; + + public: static CounterStats create(const std::vector& vals) { + if (vals.empty()) { + return CounterStats{}; + } unsigned n = vals.size(); double sum = std::accumulate(vals.begin(), vals.end(), 0.0); double mean = sum / n; @@ -56,10 +67,6 @@ struct CounterStats { return CounterStats(sum, min, max, mean, std); } - CounterStats(double sum, double min, double max, double mean, double std) - : sum(sum), minVal(min), maxVal(max), meanVal(mean), stdVal(std) { - } - const double sum{0}; const double minVal{0}; const double maxVal{0}; diff --git a/lib/runtime/AllocationTracking.cpp b/lib/runtime/AllocationTracking.cpp index 552753cd..de4d86c3 100644 --- a/lib/runtime/AllocationTracking.cpp +++ b/lib/runtime/AllocationTracking.cpp @@ -146,7 +146,7 @@ AllocState AllocationTracker::doAlloc(const void* addr, int typeId, size_t count } } else if (unlikely(addr == nullptr)) { recorder.incNullAddr(); - LOG_ERROR("Zero-size allocation " << toString(addr, typeId, count, retAddr)); + LOG_ERROR("Nullptr allocation " << toString(addr, typeId, count, retAddr)); return status | AllocState::NULL_PTR | AllocState::ADDR_SKIPPED; } diff --git a/lib/runtime/CMakeLists.txt b/lib/runtime/CMakeLists.txt index c26fabaa..6372b2af 100644 --- a/lib/runtime/CMakeLists.txt +++ b/lib/runtime/CMakeLists.txt @@ -43,9 +43,15 @@ if(SOFTCOUNTERS) endif() if(ENABLE_TSAN) - #message("Building with thread-sanitizer") - target_compile_options(typeart-rt PRIVATE -fsanitize=thread) - target_link_options(typeart-rt PRIVATE -fsanitize=thread) + target_tsan_options(typeart-rt) +endif() + +if(ENABLE_ASAN) + target_asan_options(typeart-rt) +endif() + +if(ENABLE_UBSAN) + target_ubsan_options(typeart-rt) endif() if(USE_BTREE) diff --git a/lib/runtime/TypeResolution.cpp b/lib/runtime/TypeResolution.cpp index c85b2d82..d3b340db 100644 --- a/lib/runtime/TypeResolution.cpp +++ b/lib/runtime/TypeResolution.cpp @@ -104,13 +104,13 @@ TypeResolution::TypeArtStatus TypeResolution::getTypeInfoInternal(const void* ba assert(offset < containerInfo.extent && "Something went wrong with the base address computation"); TypeArtStatus status; - int subType; + int subType{-1}; const void* subTypeBaseAddr; - size_t subTypeOffset; - size_t subTypeCount; + size_t subTypeOffset{0}; + size_t subTypeCount{0}; const StructTypeInfo* structInfo = &containerInfo; - bool resolve = true; + bool resolve{true}; // Resolve type recursively, until the address matches exactly while (resolve) { @@ -142,8 +142,8 @@ TypeResolution::TypeArtStatus TypeResolution::getTypeInfoInternal(const void* ba TypeResolution::TypeArtStatus TypeResolution::getTypeInfo(const void* addr, const void* basePtr, const PointerInfo& ptrInfo, int* type, size_t* count) const { int containingType = ptrInfo.typeId; - size_t containingTypeCount; - size_t internalOffset; + size_t containingTypeCount{0}; + size_t internalOffset{0}; // First, retrieve the containing type TypeArtStatus status = getContainingTypeInfo(addr, basePtr, ptrInfo, &containingTypeCount, &internalOffset); @@ -169,7 +169,7 @@ TypeResolution::TypeArtStatus TypeResolution::getTypeInfo(const void* addr, cons // Resolve struct recursively const auto* structInfo = typeDB.getStructInfo(containingType); if (structInfo != nullptr) { - const void* containingTypeAddr = addByteOffset(addr, -internalOffset); + const void* containingTypeAddr = addByteOffset(addr, -std::ptrdiff_t(internalOffset)); return getTypeInfoInternal(containingTypeAddr, internalOffset, *structInfo, type, count); } return TA_INVALID_ID; @@ -195,8 +195,8 @@ TypeResolution::TypeArtStatus TypeResolution::getContainingTypeInfo(const void* if (addr >= blockEnd) { const std::ptrdiff_t offset = static_cast(addr) - static_cast(basePtr); const auto oob_index = (offset / typeSize) - basePtrInfo.count + 1; - LOG_ERROR("Out of bounds for the lookup: (" << debug::toString(addr, basePtrInfo) - << ") #Elements too far: " << oob_index); + LOG_WARNING("Out of bounds for the lookup: (" << debug::toString(addr, basePtrInfo) + << ") #Elements too far: " << oob_index); return TA_UNKNOWN_ADDRESS; } diff --git a/lib/support/Logger.h b/lib/support/Logger.h index 2668dffe..d85dcdc7 100644 --- a/lib/support/Logger.h +++ b/lib/support/Logger.h @@ -8,7 +8,7 @@ #ifndef LIB_LOGGER_H_ #define LIB_LOGGER_H_ -#include +#include "llvm/Support/raw_ostream.h" #ifndef LOG_LEVEL /* diff --git a/lib/support/MPILogger.cpp b/lib/support/MPILogger.cpp index 708e090e..d73a8c4b 100644 --- a/lib/support/MPILogger.cpp +++ b/lib/support/MPILogger.cpp @@ -1,7 +1,12 @@ #include "Logger.h" -#include "mpi.h" +#include "llvm/Support/raw_ostream.h" + +#include #include +#include +#include +#include #include inline std::vector getRanks() { diff --git a/lib/typelib/TypeDB.cpp b/lib/typelib/TypeDB.cpp index b65a1549..ac08870a 100644 --- a/lib/typelib/TypeDB.cpp +++ b/lib/typelib/TypeDB.cpp @@ -4,8 +4,10 @@ #include "TypeDB.h" -//#include FIXME why needed? +#include "typelib/TypeInterface.h" + #include +#include namespace typeart { @@ -33,7 +35,7 @@ void TypeDB::clear() { } bool TypeDB::isBuiltinType(int id) const { - return id < TA_NUM_VALID_IDS; + return id >= TA_INT8 && id < TA_NUM_VALID_IDS; } bool TypeDB::isReservedType(int id) const { diff --git a/lib/typelib/TypeDB.h b/lib/typelib/TypeDB.h index 5f8f6220..daa4efee 100644 --- a/lib/typelib/TypeDB.h +++ b/lib/typelib/TypeDB.h @@ -8,6 +8,7 @@ #include "TypeInterface.h" #include +#include #include #include #include diff --git a/lib/typelib/TypeIO.cpp b/lib/typelib/TypeIO.cpp index 7579ce56..a7460579 100644 --- a/lib/typelib/TypeIO.cpp +++ b/lib/typelib/TypeIO.cpp @@ -5,17 +5,18 @@ #include "TypeIO.h" #include "TypeDB.h" -#include "TypeInterface.h" #include "support/Logger.h" -#include "llvm/Support/ErrorOr.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" -#include +#include +#include +#include using namespace llvm::yaml; diff --git a/lib/typelib/TypeIO.h b/lib/typelib/TypeIO.h index 60dd35f9..69b5d1d5 100644 --- a/lib/typelib/TypeIO.h +++ b/lib/typelib/TypeIO.h @@ -5,7 +5,6 @@ #ifndef LLVM_MUST_SUPPORT_CONFIGIO_H #define LLVM_MUST_SUPPORT_CONFIGIO_H -#include #include namespace typeart { diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 1c52e930..b59187ef 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -21,13 +21,24 @@ function(configure_typeart_script input output) set(TYPEART_ANALYSIS_PLUGIN meminstfinderpass.so) set(TYPEART_PLUGIN typeartpass.so) set(TYPEART_INCLUDE_DIRS -I${PROJECT_SOURCE_DIR}/lib/typelib) + set(TYPEART_SAN_FLAGS "") if(ENABLE_TSAN) - set(TYPEART_SAN_FLAGS "-fsanitize=thread") - else() - set(TYPEART_SAN_FLAGS "") + target_tsan_flags(TYPEART_SAN_FLAGS) + endif() + + if(ENABLE_ASAN) + target_asan_flags(asan_flags) + set(TYPEART_SAN_FLAGS ${TYPEART_SAN_FLAGS} ${asan_flags}) endif() + if(ENABLE_UBSAN) + target_ubsan_flags(ubsan_flags) + set(TYPEART_SAN_FLAGS ${TYPEART_SAN_FLAGS} ${ubsan_flags}) + endif() + + list(JOIN TYPEART_SAN_FLAGS " " TYPEART_SAN_FLAGS) + # To get execute permission: create run.sh in the binary dir, and copy it to scripts folder with permission make_executable(${input} ${output}) endfunction() diff --git a/scripts/apply.sh.in b/scripts/apply.sh.in index b47259c8..70fbba19 100644 --- a/scripts/apply.sh.in +++ b/scripts/apply.sh.in @@ -6,6 +6,8 @@ ta_more_args="" with_omp=0 omp_flags="" skip_typeart=0 +sanitizer_flags="" +with_thread=0 shift # skip over $1 while (( "$#" )); do @@ -63,21 +65,23 @@ if [ -e "types.yaml" ]; then rm "types.yaml" fi +sanitizer_flags="@TYPEART_SAN_FLAGS@" + function make_no_optim() { # Order: heap and stack/global together, no optimization pass if [ $skip_typeart == 0 ]; then - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args -S 2>&1 + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args -S 2>&1 else - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - 2>&1 + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - 2>&1 fi } function make_with_optim() { # Order: heap, optimize, alloca with additional args.. if [ $skip_typeart == 0 ]; then - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats -S | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args -S 2>&1 + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats -S | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args -S 2>&1 else - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $optimize -S 2>&1 + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" "$threads_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $optimize -S 2>&1 fi } diff --git a/scripts/run.sh.in b/scripts/run.sh.in index 6be9a5a9..afdd6c32 100644 --- a/scripts/run.sh.in +++ b/scripts/run.sh.in @@ -8,6 +8,7 @@ with_intercept=0 with_thread=0 omp_flags="" thread_flags="" +sanitizer_flags="" skip_typeart=0 shift # skip over $1 @@ -68,25 +69,27 @@ if [ -e "types.yaml" ]; then rm "types.yaml" fi +sanitizer_flags="@TYPEART_SAN_FLAGS@" + function make_no_optim() { # Order: heap and stack/global together, no optimization pass if [ $skip_typeart == 0 ]; then - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args | llc -x=ir -filetype=obj -o "$tmpfile".o + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args | llc -x=ir -filetype=obj -o "$tmpfile".o else # First create types.yaml - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args > /dev/null - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | llc -x=ir -filetype=obj -o "$tmpfile".o + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-alloca -typeart-stats $ta_more_args > /dev/null + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | llc -x=ir -filetype=obj -o "$tmpfile".o fi } function make_with_optim() { # Order: heap, optimize, alloca with additional args.. if [ $skip_typeart == 0 ]; then - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats $ta_more_args | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args | llc -x=ir -filetype=obj -o "$tmpfile".o + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats $ta_more_args | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args | llc -x=ir -filetype=obj -o "$tmpfile".o else # First create types.yaml - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats $ta_more_args | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args > /dev/null - $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" @TYPEART_SAN_FLAGS@ -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $optimize | llc -x=ir -filetype=obj -o "$tmpfile".o + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $typeart_plugin -typeart-stats $ta_more_args | opt $optimize -S | opt $typeart_plugin -typeart-no-heap -typeart-alloca -typeart-stats $ta_more_args > /dev/null + $compiler @TYPEART_INCLUDE_DIRS@ "$omp_flags" $sanitizer_flags -O1 -Xclang -disable-llvm-passes -S -emit-llvm "$target" -o - | opt $optimize | llc -x=ir -filetype=obj -o "$tmpfile".o fi } @@ -98,7 +101,7 @@ function compile() { make_with_optim fi - $compiler "$tmpfile".o "$omp_flags" "$threads_flags" @TYPEART_SAN_FLAGS@ -L@TYPEART_RT_DIR@ -ltypeart-rt -o "$tmpfile".exe + $compiler "$tmpfile".o "$omp_flags" "$threads_flags" $sanitizer_flags -L@TYPEART_RT_DIR@ -ltypeart-rt -o "$tmpfile".exe } compile diff --git a/test/pass/misc/06_unknown_type.llin b/test/pass/misc/06_unknown_type.llin new file mode 100644 index 00000000..89139806 --- /dev/null +++ b/test/pass/misc/06_unknown_type.llin @@ -0,0 +1,34 @@ +; RUN: cat %s | %apply-typeart -typeart-alloca -S 2>&1 | FileCheck %s + +define dso_local i32 @main() #0 { +; CHECK: [Error]{{.*}}Target type of casted allocation is unknown. Not instrumenting.{{.*}}%3 = call noalias i8* @malloc(i64 12) +; CHECK: [Error]{{.*}}Unknown stack type. Not instrumenting. i1 + %1 = alloca i1*, align 8 +; FIXME: no need to instrument pointer type as stack var +; CHECK: call void @__typeart_alloc_stack(i8* %2, i32 10, i64 1) + %2 = alloca i1, align 4 + %3 = call noalias i8* @malloc(i64 12) #3 + %4 = bitcast i8* %3 to i1* + store i1* %4, i1** %1, align 8, !tbaa !2 + store i1 2, i1* %2, align 4, !tbaa !6 + ret i32 0 +} + +declare dso_local noalias i8* @malloc(i64) #2 + +attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind willreturn } +attributes #2 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i1 1, !"wchar_size", i1 4} +!1 = !{!"clang version 10.0.1 (https://github.com/llvm/llvm-project.git ef32c611aa214dea855364efd7ba451ec5ec3f74)"} +!2 = !{!3, !3, i64 0} +!3 = !{!"any pointer", !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"} +!6 = !{!7, !7, i64 0} +!7 = !{!"int", !4, i64 0} diff --git a/test/runtime/20_softcounter_max.c b/test/runtime/20_softcounter_max.c index b2f74fc5..f3b6da32 100644 --- a/test/runtime/20_softcounter_max.c +++ b/test/runtime/20_softcounter_max.c @@ -1,4 +1,4 @@ -// RUN: %run %s -o -O1 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=detect_leaks=0 %run %s -o -O1 2>&1 | FileCheck %s // REQUIRES: softcounter #include diff --git a/test/runtime/22_threads_stack.cpp b/test/runtime/22_threads_stack.cpp index f15a2719..31856e52 100644 --- a/test/runtime/22_threads_stack.cpp +++ b/test/runtime/22_threads_stack.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s --thread 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s --thread 2>&1 | FileCheck %s // REQUIRES: thread // clang-format on @@ -24,7 +25,9 @@ int main(int argc, char** argv) { t1.join(); t2.join(); - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // CHECK: [Trace] Free 0x{{.*}} 0 int8 1 7 // CHECK: [Trace] Free 0x{{.*}} 6 double 8 1 diff --git a/test/runtime/23_threads_heap.cpp b/test/runtime/23_threads_heap.cpp index ac0f92d4..b9d69496 100644 --- a/test/runtime/23_threads_heap.cpp +++ b/test/runtime/23_threads_heap.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s --thread 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s --thread 2>&1 | FileCheck %s // REQUIRES: thread && softcounter // clang-format on @@ -28,7 +29,9 @@ int main(int argc, char** argv) { t2.join(); t3.join(); - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // CHECK: Allocation type detail (heap, stack, global) // CHECK: 6 : 3000 , 0 , 0 , double // CHECK: Free allocation type detail (heap, stack) diff --git a/test/runtime/24_threads_type_check.cpp b/test/runtime/24_threads_type_check.cpp index 3a401072..10c4d3c0 100644 --- a/test/runtime/24_threads_type_check.cpp +++ b/test/runtime/24_threads_type_check.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s --thread 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s --thread 2>&1 | FileCheck %s // REQUIRES: thread && softcounter // clang-format on @@ -54,7 +55,8 @@ int main(int argc, char** argv) { free(f1); free(f2); - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + // CHECK-NOT: Error // CHECK: Allocation type detail (heap, stack, global) // CHECK: 6 : 3000 , 0 , 0 , double diff --git a/test/runtime/25_omp_stack.c b/test/runtime/25_omp_stack.c index 85f4550b..11560fa5 100644 --- a/test/runtime/25_omp_stack.c +++ b/test/runtime/25_omp_stack.c @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s --omp 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s --omp 2>&1 | FileCheck %s // REQUIRES: openmp // clang-format on @@ -18,7 +19,9 @@ int main(int argc, char** argv) { f(); } - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // CHECK: [Trace] Free 0x{{.*}} 0 int8 1 4 // CHECK-DAG: [Trace] Free 0x{{.*}} 6 double 8 1 diff --git a/test/runtime/26_omp_heap.c b/test/runtime/26_omp_heap.c index 4f2464ff..99a64fc0 100644 --- a/test/runtime/26_omp_heap.c +++ b/test/runtime/26_omp_heap.c @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s --omp 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s --omp 2>&1 | FileCheck %s // REQUIRES: openmp && softcounter // clang-format on @@ -26,7 +27,9 @@ int main(int argc, char** argv) { repeat_alloc_free(n); } - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // CHECK: Allocation type detail (heap, stack, global) // CHECK: 6 : 3000 , 0 , 0 , double // CHECK: Free allocation type detail (heap, stack) diff --git a/test/runtime/27_omp_softcounter.c b/test/runtime/27_omp_softcounter.c index 6abaec3b..6661506c 100644 --- a/test/runtime/27_omp_softcounter.c +++ b/test/runtime/27_omp_softcounter.c @@ -1,4 +1,7 @@ // clang-format off +// RUN: %run %s --omp --call-filter 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN +// RUN: %run %s -o -O2 --omp --call-filter 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN + // RUN: %run %s -o -O2 --omp --call-filter 2>&1 | FileCheck %s // RUN: %run %s --omp --call-filter 2>&1 | FileCheck %s // REQUIRES: openmp && softcounter @@ -29,6 +32,8 @@ int main(int argc, char** argv) { ptr(n); + // CHECK-TSAN-NOT: ThreadSanitizer + // CHECK: [Trace] TypeART Runtime Trace // CHECK-NOT: [Error] // CHECK: Alloc Stats from softcounters diff --git a/test/runtime/28_omp_softcounter_stack.c b/test/runtime/28_omp_softcounter_stack.c index 1c622453..5c340283 100644 --- a/test/runtime/28_omp_softcounter_stack.c +++ b/test/runtime/28_omp_softcounter_stack.c @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s -o -O0 --omp 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s -o -O0 --omp 2>&1 | FileCheck %s // REQUIRES: openmp && softcounter // clang-format on @@ -28,6 +29,8 @@ int main(int argc, char** argv) { const int n = 100; ptr(n); + // CHECK-TSAN-NOT: ThreadSanitizer + // CHECK: [Trace] TypeART Runtime Trace // TODO: CHECK-NOT: [Error] - Currently we get 'Pointer already in map' followed by 'Free on unregistered address' // CHECK: Alloc Stats from softcounters diff --git a/test/runtime/29_threads_concurrent_rwx.cpp b/test/runtime/29_threads_concurrent_rwx.cpp index d3c63a61..b1dc2324 100644 --- a/test/runtime/29_threads_concurrent_rwx.cpp +++ b/test/runtime/29_threads_concurrent_rwx.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: %run %s -o -O1 --thread --manual 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: %run %s -o -O1 --thread --manual 2>&1 | FileCheck %s // REQUIRES: thread && softcounter // clang-format on @@ -14,18 +15,19 @@ #include std::atomic_bool stop{false}; +const size_t extent{1}; template void repeat_alloc(S s, E e) { - std::for_each(s, e, [&](auto elem) { __typeart_alloc(reinterpret_cast(elem), int{6}, size_t{20}); }); + std::for_each(s, e, [&](auto elem) { __typeart_alloc(reinterpret_cast(elem), int{6}, extent); }); } template void repeat_alloc_free_v2(S s, E e) { using namespace std::chrono_literals; std::for_each(s, e, [&](auto elem) { - __typeart_alloc(reinterpret_cast(elem), int{7}, size_t{10}); - std::this_thread::sleep_for(1ms); + __typeart_alloc(reinterpret_cast(elem), int{7}, extent); + // std::this_thread::sleep_for(1ms); __typeart_free(reinterpret_cast(elem)); }); } @@ -38,7 +40,7 @@ void repeat_type_check(S s, E e) { size_t count_check{0}; typeart_status status = typeart_get_type(reinterpret_cast(addr), &id_result, &count_check); if (status == TA_OK) { - if (count_check != size_t{20}) { + if (count_check != extent) { fprintf(stderr, "[Error]: Length mismatch of %i (%#02x) is: type=%i count=%zu\n", addr, addr, id_result, count_check); } @@ -53,17 +55,19 @@ void repeat_type_check(S s, E e) { std::vector unique_rand(const unsigned size) { std::vector vec(size); - std::iota(vec.begin(), vec.end(), 1); - + unsigned cnt{1}; + std::generate(vec.begin(), vec.end(), [&cnt]() { + auto current = cnt; + cnt += extent * sizeof(double); + return current; + }); std::mt19937 g(42); - std::shuffle(vec.begin(), vec.end(), g); - return vec; } int main(int argc, char** argv) { - constexpr unsigned size = 200; + constexpr unsigned size = 100; auto vec = unique_rand(size); auto beg = std::begin(vec); auto h = beg + (size / 2); @@ -71,7 +75,6 @@ int main(int argc, char** argv) { std::thread malloc_1(repeat_alloc, beg, h); std::thread malloc_2(repeat_alloc_free_v2, h, e); - std::thread check_1(repeat_type_check, beg, h); malloc_1.join(); @@ -81,17 +84,7 @@ int main(int argc, char** argv) { check_1.join(); - // CHECK-NOT: [Error] - - // CHECK: Alloc Stats from softcounters - // CHECK: Distinct Addresses checked : 100 , - , - - - // CHECK: Allocation type detail (heap, stack, global) - // CHECK: 6 : 100 , 0 , 0 , double - // CHECK: 7 : 100 , 0 , 0 , float128 - - // We free only 3/4 of allocations - // CHECK: Free allocation type detail (heap, stack) - // CHECK: 7 : 100 , 0 , float128 + // CHECK-TSAN-NOT: ThreadSanitizer + // CHECK-NOT: Error return 0; } diff --git a/test/runtime/30_omp_concurrent_w.cpp b/test/runtime/30_omp_concurrent_w.cpp index 7c02183b..028420c6 100644 --- a/test/runtime/30_omp_concurrent_w.cpp +++ b/test/runtime/30_omp_concurrent_w.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: OMP_NUM_THREADS=3 %run %s -o -O1 --omp --manual 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: OMP_NUM_THREADS=3 %run %s -o -O1 --omp --manual 2>&1 | FileCheck %s // REQUIRES: openmp && softcounter // clang-format on @@ -59,7 +60,9 @@ int main(int argc, char** argv) { { repeat_dealloc(h1, h2); } } - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // CHECK: Allocation type detail (heap, stack, global) // CHECK: 6 : 300 , 0 , 0 , double diff --git a/test/runtime/31_omp_overwrite.cpp b/test/runtime/31_omp_overwrite.cpp index de3b3749..e8cebbf3 100644 --- a/test/runtime/31_omp_overwrite.cpp +++ b/test/runtime/31_omp_overwrite.cpp @@ -1,4 +1,5 @@ // clang-format off +// RUN: OMP_NUM_THREADS=3 %run %s -o -O1 --omp --manual 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN // RUN: OMP_NUM_THREADS=3 %run %s -o -O1 --omp --manual 2>&1 | FileCheck %s // REQUIRES: openmp && softcounter // clang-format on @@ -42,7 +43,9 @@ int main(int argc, char** argv) { { repeat_alloc(beg, e); } } - // CHECK-NOT: [Error] + // CHECK-TSAN-NOT: ThreadSanitizer + + // CHECK-NOT: Error // 3 Threads, using the same 100 pointers, i.e., 200 are overriden: // CHECK: Alloc Stats from softcounters diff --git a/test/runtime/32_addresses.c b/test/runtime/32_addresses.c new file mode 100644 index 00000000..3dfc576c --- /dev/null +++ b/test/runtime/32_addresses.c @@ -0,0 +1,20 @@ +// RUN: %run %s --manual 2>&1 | FileCheck %s + +#include "../../lib/runtime/CallbackInterface.h" + +#include + +int main(int argc, char** argv) { + __typeart_alloc((const void*)0, 6, 1); + __typeart_alloc((const void*)1, 5, 0); + __typeart_alloc((const void*)0, 6, 0); + __typeart_alloc((const void*)2, 7, 1); // OK + + return 0; +} +// TODO disable Trace logs for early return? + +// CHECK: [Error]{{.*}}:Nullptr allocation 0x0 6 double 8 1 +// CHECK: [Warning]{{.*}}:Zero-size allocation 0x1 5 float 4 0 +// CHECK: [Error]{{.*}}:Zero-size and nullptr allocation 0x0 6 double 8 0 +// CHECK: [Trace] Alloc 0x2 7 float128 16 1 \ No newline at end of file diff --git a/test/runtime/33_inexistant_typecheck.c b/test/runtime/33_inexistant_typecheck.c new file mode 100644 index 00000000..f05d2c45 --- /dev/null +++ b/test/runtime/33_inexistant_typecheck.c @@ -0,0 +1,37 @@ +// RUN: %run %s --manual 2>&1 | FileCheck %s + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include +#include + +int main(int argc, char** argv) { + const int addr = 2; + const int type = -1; + const size_t extent = 2; + __typeart_alloc((const void*)addr, type, extent); + + int id_result = 0; + size_t count_check = 0; + typeart_status status = typeart_get_type((const void*)addr, &id_result, &count_check); + + if (status != TA_OK) { + fprintf(stderr, "[Error]: Status not OK: %i\n", status); + } else { + if (extent != count_check) { + fprintf(stderr, "[Error]: Count check failed %zu\n", count_check); + } + if (type != id_result) { + fprintf(stderr, "[Error]: ID check failed %i\n", id_result); + } + fprintf(stderr, "[Trace]: Status OK: %i %zu\n", id_result, count_check); + } + return 0; +} + +// TODO the runtime continues, even if type is unkown. + +// CHECK: [Error]{{.*}}Allocation of unknown type 0x2 -1 UnknownStruct 0 2 +// CHECK: [Trace] Alloc 0x2 -1 UnknownStruct 0 2 +// CHECK: Status OK: -1 2 diff --git a/test/runtime/34_off_by_n.cpp b/test/runtime/34_off_by_n.cpp new file mode 100644 index 00000000..553813b5 --- /dev/null +++ b/test/runtime/34_off_by_n.cpp @@ -0,0 +1,56 @@ +// clang-format off +// RUN: %run %s --manual 2>&1 | FileCheck %s +// clang-format on + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include + +int main(int argc, char** argv) { + const int type{6}; + const size_t extent{6}; + const size_t expected_count{1}; + + const auto check = [&](double* addr) { + int id_result{-1}; + size_t count_check{0}; + typeart_status status = typeart_get_type(reinterpret_cast(addr), &id_result, &count_check); + + if (status == TA_OK) { + if (count_check != expected_count) { + fprintf(stderr, "[Error]: Count not expected: %zu\n", count_check); + } + if (id_result != type) { + fprintf(stderr, "[Error]: Type not expected: %i\n", id_result); + } + } else { + fprintf(stderr, "[Check]: Status: %i\n", status); + } + }; + + auto* d = new double[extent]; + + __typeart_alloc(reinterpret_cast(&d[0]), type, 1); + __typeart_alloc(reinterpret_cast(&d[1]), type, 1); + + // CHECK-NOT: [Error] + check(&d[0]); + check(&d[1]); + // CHECK: {{.*}}:Out of bounds for the lookup: (0x{{[0-9a-f]+}} 6 double 8 1 (0x{{[0-9a-f]+}})) #Elements too far: 1 + // CHECK: [Check]: Status: 1 + check(&d[2]); // one off + // CHECK: {{.*}}:Out of bounds for the lookup: (0x{{[0-9a-f]+}} 6 double 8 1 (0x{{[0-9a-f]+}})) #Elements too far: 4 + // CHECK: [Check]: Status: 1 + check(&d[5]); // four off + + // CHECK-NOT: {{.*}}:Out of bounds for the lookup + // CHECK-NOT: [Error] + // CHECK: [Check]: Status: 1 + double* p_0 = (&d[0]) - 1; + check(p_0); // -1 off + + delete[] d; + + return 0; +} diff --git a/test/runtime/35_free_inexistant.cpp b/test/runtime/35_free_inexistant.cpp new file mode 100644 index 00000000..19c0c19a --- /dev/null +++ b/test/runtime/35_free_inexistant.cpp @@ -0,0 +1,53 @@ +// clang-format off +// RUN: %run %s --manual 2>&1 | FileCheck %s +// clang-format on + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include + +int main(int argc, char** argv) { + const int type{6}; + const size_t extent{6}; + const size_t expected_count{extent}; + + const auto check = [&](double* addr) { + int id_result{-1}; + size_t count_check{0}; + typeart_status status = typeart_get_type(reinterpret_cast(addr), &id_result, &count_check); + + if (status == TA_OK) { + if (count_check != expected_count) { + fprintf(stderr, "[Error]: Count not expected: %zu\n", count_check); + } + if (id_result != type) { + fprintf(stderr, "[Error]: Type not expected: %i\n", id_result); + } + } else { + fprintf(stderr, "[Check]: Status: %i\n", status); + } + }; + + auto* d = new double[extent]; + + // CHECK: [Error]{{.*}}Free on nullptr + __typeart_free(nullptr); + // CHECK: [Error]{{.*}}Free on unregistered address + __typeart_free(reinterpret_cast(d)); + + // CHECK: [Trace] Alloc 0x{{[0-9a-f]+}} 6 double 8 6 + __typeart_alloc(reinterpret_cast(&d[0]), type, extent); + // CHECK-NOT: [Error] + // CHECK-NOT: [Check] + check(&d[0]); + + // CHECK: [Trace] Free 0x{{[0-9a-f]+}} 6 double 8 6 + __typeart_free(reinterpret_cast(d)); + // CHECK: [Error]{{.*}}Free on unregistered address + __typeart_free(reinterpret_cast(d)); + + delete[] d; + + return 0; +} diff --git a/test/runtime/36_stack_dealloc.cpp b/test/runtime/36_stack_dealloc.cpp new file mode 100644 index 00000000..bf4d0ead --- /dev/null +++ b/test/runtime/36_stack_dealloc.cpp @@ -0,0 +1,39 @@ +// clang-format off +// RUN: %run %s --manual 2>&1 | FileCheck %s +// clang-format on + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include + +int main(int argc, char** argv) { + const int type{6}; + const size_t extent{6}; + double d[extent]; + + // CHECK: [Error]{{.*}}Stack is smaller than requested de-allocation count. alloca_count: 1. size: 0 + __typeart_leave_scope(1); + // CHECK: [Error]{{.*}}Stack is smaller than requested de-allocation count. alloca_count: 12. size: 0 + __typeart_leave_scope(12); + + // CHECK: [Trace] Alloc 0x{{[0-9a-f]+}} 6 double 8 6 + __typeart_alloc_stack(reinterpret_cast(&d[0]), type, extent); + + // CHECK: [Trace] Freeing stack (1) 1 + // CHECK: [Trace] Free 0x{{[0-9a-f]+}} 6 double 8 6 + // CHECK: [Trace] Stack after free: 0 + __typeart_leave_scope(1); + + // CHECK: [Error]{{.*}}Stack is smaller than requested de-allocation count. alloca_count: 1. size: 0 + __typeart_leave_scope(1); + + // CHECK: [Trace] Alloc 0x{{[0-9a-f]+}} 6 double 8 1 + __typeart_alloc_stack(reinterpret_cast(&d[0]), type, 1); + // CHECK: [Trace] Alloc 0x{{[0-9a-f]+}} 6 double 8 1 + __typeart_alloc_stack(reinterpret_cast(&d[1]), type, 1); + // CHECK: [Error]{{.*}}Stack is smaller than requested de-allocation count. alloca_count: 3. size: 2 + // CHECK: [Trace] Freeing stack (2) 2 + __typeart_leave_scope(3); + return 0; +} diff --git a/test/runtime/38_resolve_struct.c b/test/runtime/38_resolve_struct.c new file mode 100644 index 00000000..36fb1b80 --- /dev/null +++ b/test/runtime/38_resolve_struct.c @@ -0,0 +1,66 @@ +// RUN: %run %s --manual 2>&1 | FileCheck %s + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include +#include +#include + +struct Datastruct { + int start; + double middle; + float end[2]; +}; + +void type_check(const void* addr) { + int id_result = 0; + size_t count_check = 0; + typeart_status status; + status = typeart_get_type(addr, &id_result, &count_check); + + if (status != TA_OK) { + fprintf(stderr, "[Error]: Status not OK: %i for %p\n", status, addr); + } else { + fprintf(stderr, "Status OK: %i %zu\n", id_result, count_check); + } +} + +void type_check_containing(const void* addr) { + size_t offset = 0; + const void* base_adrr = NULL; + int id_result = 0; + size_t count_check = 0; + typeart_status status; + + status = typeart_get_containing_type(addr, &id_result, &count_check, &base_adrr, &offset); + + if (status != TA_OK) { + fprintf(stderr, "[Error]: Status not OK: %i for %p\n", status, addr); + } else { + fprintf(stderr, "Status OK: %i %zu %zu %p\n", id_result, count_check, offset, base_adrr); + } +} + +int main(int argc, char** argv) { + // CHECK-NOT: [Error] + + struct Datastruct data; + __typeart_alloc((const void*)&data, 257, 1); + + // CHECK: Status OK: 6 1 + type_check((const void*)&data.middle); + + struct Datastruct data_ar[3]; + // CHECK: [Trace] Alloc [[POINTER:0x[0-9a-f]+]] 257 + __typeart_alloc((const void*)&data_ar[0], 257, 3); + + // CHECK: Status OK: 5 2 + type_check((const void*)&data_ar[2].end); + // CHECK: Status OK: 257 1 16 [[POINTER]] + type_check_containing((const void*)&data_ar[2].end); + // CHECK: Status OK: 257 2 20 [[POINTER]] + type_check_containing((const void*)&data_ar[1].end[1]); + + return 0; +} diff --git a/test/runtime/39_typefile.c b/test/runtime/39_typefile.c new file mode 100644 index 00000000..310d5067 --- /dev/null +++ b/test/runtime/39_typefile.c @@ -0,0 +1,19 @@ +// RUN: TA_TYPE_FILE=%p%{pathsep}%t %run %s 2>&1 | FileCheck %s --check-prefix=CHECK-FAIL-FILE +// XFAIL: * + +#include +#include + +struct Datastruct { + int start; + double middle; + float end; +}; + +int main(int argc, char** argv) { + struct Datastruct data = {0}; + return data.start; +} + +// Nonexistant (using environment var) file aborts runtime: +// CHECK-FAIL-FILE: [Fatal]{{.*}}Failed to load recorded types \ No newline at end of file diff --git a/test/runtime/40_ret_addr.c b/test/runtime/40_ret_addr.c new file mode 100644 index 00000000..fca9d40d --- /dev/null +++ b/test/runtime/40_ret_addr.c @@ -0,0 +1,20 @@ +// RUN: %run %s --manual 2>&1 | FileCheck %s + +#include "../../lib/runtime/CallbackInterface.h" +#include "util.h" + +#include +#include + +int main(int argc, char** argv) { + const void* ret_check = NULL; + const void* addr = 1; + + typeart_get_return_address(addr, &ret_check); + if (ret_check != NULL) { + fprintf(stderr, "[Error] Ret address mismatch expected NULL but have %p\n", ret_check); + } + return 0; +} + +// CHECK-NOT: [Error]