cmake_minimum_required(VERSION 3.10) project(SafeInt_clang VERSION 3.0.26) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) # Runtime tests are: # - default # - without built-in 128-bit support # - without intrinsics # Compile time tests are: # - default C++11 # - C++14, C++17 # - TODO - consider adding in 20, 23 just to see if anything breaks # - compile without exceptions # test for clang++ find_program(CLANG_PLUS_PLUS "clang++") if(NOT CLANG_PLUS_PLUS) message(STATUS "Clang compiler not available, skipping") else() message(STATUS "clang++ available, configuring clang tests") set(CMAKE_CXX_COMPILER ${CLANG_PLUS_PLUS}) # the standard level is already at C++11, which is what we need for runtime tests add_compile_options(-O3 -ftrapv) # Note - the test matrix here is as follows: # int128 is available (best case) # no int128, but we do have intrinsics # fallback C++ code, which is less efficient # # Coverage will vary, depending on the capabilities of the platform. # We cannot force coverage for options that aren't supported. # Tests are: # SafeIntTest_clang - this will test the best option this platform has # SafeIntTest_clang_NoIntrinsic - ensures that the older (potentially more fragile) code is tested # SafeIntTest_clang_NoInt128 - if we do have intrinsic support, this will force testing this, # else is the same as previous. # This will test whatever the mainline code can do, typically using int128 add_executable(SafeIntTest_clang ../AddVerify.cpp ../AddTestCase.cpp ../CastVerify.cpp ../DivVerify.cpp ../DivTestCase.cpp ../IncDecVerify.cpp ../ModVerify.cpp ../MultVerify.cpp ../MultTestCase.cpp ../SubVerify.cpp ../SubTestCase.cpp ../TestMain.cpp ../TestMain.h ../../SafeInt.hpp ) target_compile_options(SafeIntTest_clang PUBLIC -Werror -fsanitize-trap=undefined) # Forces use of the older, less efficient code that can't use either int128 or intrinsics add_executable(SafeIntTest_clang_NoIntrinsic ../AddVerify.cpp ../AddTestCase.cpp ../CastVerify.cpp ../DivVerify.cpp ../DivTestCase.cpp ../IncDecVerify.cpp ../ModVerify.cpp ../MultVerify.cpp ../MultTestCase.cpp ../SubVerify.cpp ../SubTestCase.cpp ../TestMain.cpp ../TestMain.h ../../SafeInt.hpp ) target_compile_definitions(SafeIntTest_clang_NoIntrinsic PUBLIC "SAFEINT_USE_INTRINSICS=0" "SAFEINT_HAS_INT128=0") target_compile_options(SafeIntTest_clang_NoIntrinsic PUBLIC -Werror -fsanitize-trap=undefined) # Forces use of either intrinsics or the older code add_executable(SafeIntTest_clang_NoInt128 ../AddVerify.cpp ../AddTestCase.cpp ../CastVerify.cpp ../DivVerify.cpp ../DivTestCase.cpp ../IncDecVerify.cpp ../ModVerify.cpp ../MultVerify.cpp ../MultTestCase.cpp ../SubVerify.cpp ../SubTestCase.cpp ../TestMain.cpp ../TestMain.h ../../SafeInt.hpp ) target_compile_definitions(SafeIntTest_clang_NoInt128 PUBLIC "SAFEINT_HAS_INT128=0") target_compile_options(SafeIntTest_clang_NoInt128 PUBLIC -Werror -fsanitize-trap=undefined) # compilation tests, these are good if they just build add_executable(CompileTest_clang ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang PUBLIC -Wall -Wextra -Werror) add_executable(CompileTest_clang14 ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang14 PUBLIC -Wall -Wextra -Werror -std=c++14) add_executable(CompileTest_clang17 ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang17 PUBLIC -Wall -Wextra -Werror -std=c++17) add_executable(CompileTest_clang14_NoEH ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang14_NoEH PUBLIC -Wall -Wextra -Werror -std=c++14 -fno-exceptions) add_executable(CompileTest_clang17_NoEH ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang17_NoEH PUBLIC -Wall -Wextra -Werror -std=c++17 -fno-exceptions) add_executable(CompileTest_clang98 ../CompileTest.cpp ../ConstExpr.cpp ../CleanCompile.cpp ../../SafeInt.hpp ) target_compile_options(CompileTest_clang98 PUBLIC -D SAFEINT_USE_CPLUSCPLUS_98 -Wall -Wextra -Werror -std=c++98 -fno-exceptions) add_executable(safe_math_test_clang ../c_safe_math/safe_math_test.c ../c_safe_math/safe_math_test.h ../c_safe_math/safe_math_test_add.cpp ../c_safe_math/safe_math_test_div.cpp ../c_safe_math/safe_math_test_mult.cpp ../c_safe_math/safe_math_test_sub.cpp ../AddTestCase.cpp ../DivTestCase.cpp ../MultTestCase.cpp ../SubTestCase.cpp ../../safe_math.h ../../safe_math_impl.h ) target_compile_definitions(safe_math_test_clang PUBLIC) target_compile_options(safe_math_test_clang PUBLIC -Wall -Wextra -Werror -Wno-old-style-cast # Ignore warning about using long long -Wno-c++98-compat-pedantic # Do not care if the test harness isn't padded precisely -Wno-padded # This should be a false positive, nodiscard is wrapped in detection logic # Note - this warning is -Wno-cxx-attribute-extension on v14 on Apple # but is -Wc++17-attribute-ext on v15 on Linux # Not worried about -Wglobal-constructors in test code -Wno-global-constructors # Enable this when upgrading to new compiler version, or if just want to check # -Weverything ) add_executable(safe_math_compile_clang ../c_safe_math/safe_math_compile.c ../c_safe_math/compile_test.c ../../safe_math.h ../../safe_math_impl.h ) target_compile_options(safe_math_compile_clang PUBLIC -Wall -Wextra -Wincompatible-pointer-types -Wreserved-identifier -Wdeclaration-after-statement -Wc++98-compat -Werror # As per clang documentation, enable this periodically to check, -Wall, -Wextra # won't give you experimental warnings. # -Weverything ) endif() enable_testing() if(CLANG_PLUS_PLUS) add_test(NAME SafeIntTest_clang COMMAND SafeIntTest_clang) add_test(NAME SafeIntTest_clang_NoIntrinsic COMMAND SafeIntTest_clang_NoIntrinsic) add_test(NAME SafeIntTest_clang_NoInt128 COMMAND SafeIntTest_clang_NoInt128) add_test(NAME safe_math_test_clang COMMAND safe_math_test_clang) set_tests_properties(SafeIntTest_clang SafeIntTest_clang_NoIntrinsic SafeIntTest_clang_NoInt128 safe_math_test_clang PROPERTIES FAIL_REGULAR_EXPRESSION "Error") endif()