Skip to content

Commit d202b82

Browse files
authored
Merge pull request #1204 from libcpr/feature/more-reliable-sanitizer-checks
Do Not Check For Sanitizers If They Are Not Enabled
2 parents 29cd461 + c491f58 commit d202b82

File tree

3 files changed

+48
-35
lines changed

3 files changed

+48
-35
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ project(cpr VERSION 1.11.2 LANGUAGES CXX)
44
math(EXPR cpr_VERSION_NUM "${cpr_VERSION_MAJOR} * 0x10000 + ${cpr_VERSION_MINOR} * 0x100 + ${cpr_VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL)
55
configure_file("${cpr_SOURCE_DIR}/cmake/cprver.h.in" "${cpr_BINARY_DIR}/cpr_generated_includes/cpr/cprver.h")
66

7-
# Only change the folder behaviour if cpr is not a subproject
7+
# Only change the folder behavior if cpr is not a subproject
88
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
99
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
1010
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake")

cmake/sanitizer.cmake

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,80 @@
1-
include(CheckCXXCompilerFlag)
21
include(CheckCXXSourceRuns)
32

43
set(ALL_SAN_FLAGS "")
54

65
# No sanitizers when cross compiling to prevent stuff like this: https://github.com/whoshuu/cpr/issues/582
76
if(NOT CMAKE_CROSSCOMPILING)
87
# Thread sanitizer
9-
set(THREAD_SAN_FLAGS "-fsanitize=thread")
10-
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
11-
set(CMAKE_REQUIRED_FLAGS "${THREAD_SAN_FLAGS}")
12-
check_cxx_source_runs("int main() { return 0; }" THREAD_SANITIZER_AVAILABLE)
13-
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
14-
# Do not add the ThreadSanitizer for builds with all sanitizers enabled because it is incompatible with other sanitizers.
8+
if(CPR_DEBUG_SANITIZER_FLAG_THREAD)
9+
set(THREAD_SAN_FLAGS "-fsanitize=thread")
10+
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
11+
set(CMAKE_REQUIRED_FLAGS "${THREAD_SAN_FLAGS}")
12+
check_cxx_source_runs("int main() { return 0; }" THREAD_SANITIZER_AVAILABLE_AND_ENABLED)
13+
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
14+
# Do not add the ThreadSanitizer for builds with all sanitizers enabled because it is incompatible with other sanitizers.
15+
endif()
1516

1617
# Address sanitizer
17-
set(ADDR_SAN_FLAGS "-fsanitize=address")
18-
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
19-
set(CMAKE_REQUIRED_FLAGS "${ADDR_SAN_FLAGS}")
20-
check_cxx_source_runs("int main() { return 0; }" ADDRESS_SANITIZER_AVAILABLE)
21-
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
22-
if(ADDRESS_SANITIZER_AVAILABLE)
23-
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${ADDR_SAN_FLAGS}")
18+
if(CPR_DEBUG_SANITIZER_FLAG_ADDR)
19+
set(ADDR_SAN_FLAGS "-fsanitize=address")
20+
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
21+
set(CMAKE_REQUIRED_FLAGS "${ADDR_SAN_FLAGS}")
22+
check_cxx_source_runs("int main() { return 0; }" ADDRESS_SANITIZER_AVAILABLE_AND_ENABLED)
23+
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
24+
if(ADDRESS_SANITIZER_AVAILABLE_AND_ENABLED)
25+
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${ADDR_SAN_FLAGS}")
26+
endif()
2427
endif()
2528

2629
# Leak sanitizer
27-
set(LEAK_SAN_FLAGS "-fsanitize=leak")
28-
check_cxx_compiler_flag(${LEAK_SAN_FLAGS} LEAK_SANITIZER_AVAILABLE)
29-
if(LEAK_SANITIZER_AVAILABLE)
30-
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${LEAK_SAN_FLAGS}")
30+
if(CPR_DEBUG_SANITIZER_FLAG_LEAK)
31+
set(LEAK_SAN_FLAGS "-fsanitize=leak")
32+
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
33+
set(CMAKE_REQUIRED_FLAGS "${LEAK_SAN_FLAGS}")
34+
check_cxx_source_runs("int main() { return 0; }" LEAK_SANITIZER_AVAILABLE_AND_ENABLED)
35+
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
36+
if(LEAK_SANITIZER_AVAILABLE_AND_ENABLED)
37+
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${LEAK_SAN_FLAGS}")
38+
endif()
3139
endif()
3240

3341
# Undefined behavior sanitizer
34-
set(UDEF_SAN_FLAGS "-fsanitize=undefined")
35-
check_cxx_compiler_flag(${UDEF_SAN_FLAGS} UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
36-
if(UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
37-
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${UDEF_SAN_FLAGS}")
42+
if(CPR_DEBUG_SANITIZER_FLAG_UB)
43+
set(UDEF_SAN_FLAGS "-fsanitize=undefined")
44+
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
45+
set(CMAKE_REQUIRED_FLAGS "${UDEF_SAN_FLAGS}")
46+
check_cxx_source_runs("int main() { return 0; }" UNDEFINED_BEHAVIOR_SANITIZER_AVAILABLE_AND_ENABLED)
47+
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
48+
if(UNDEFINED_BEHAVIOR_SANITIZER_AVAILABLE_AND_ENABLED)
49+
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${UDEF_SAN_FLAGS}")
50+
endif()
3851
endif()
3952

4053
# All sanitizer (without thread sanitizer)
41-
if(NOT ALL_SAN_FLAGS STREQUAL "")
54+
if(CPR_DEBUG_SANITIZER_FLAG_ALL AND NOT ALL_SAN_FLAGS STREQUAL "")
4255
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
4356
set(CMAKE_REQUIRED_FLAGS "${ALL_SAN_FLAGS}")
44-
check_cxx_source_runs("int main() { return 0; }" ALL_SANITIZERS_AVAILABLE)
57+
check_cxx_source_runs("int main() { return 0; }" ALL_SANITIZERS_AVAILABLE_AND_ENABLED)
4558
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
4659
endif()
4760

48-
if(CPR_DEBUG_SANITIZER_FLAG_THREAD AND THREAD_SANITIZER_AVAILABLE)
61+
if(THREAD_SANITIZER_AVAILABLE_AND_ENABLED)
4962
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during thread sanitizer builds." FORCE)
5063
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during thread sanitizer builds." FORCE)
5164
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during thread sanitizer builds" FORCE)
52-
elseif(CPR_DEBUG_SANITIZER_FLAG_ADDR AND ADDRESS_SANITIZER_AVAILABLE)
65+
elseif(ADDRESS_SANITIZER_AVAILABLE_AND_ENABLED)
5366
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during address sanitizer builds." FORCE)
5467
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during address sanitizer builds." FORCE)
5568
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during address sanitizer builds" FORCE)
56-
elseif(CPR_DEBUG_SANITIZER_FLAG_LEAK AND LEAK_SANITIZER_AVAILABLE)
69+
elseif(LEAK_SANITIZER_AVAILABLE_AND_ENABLED)
5770
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C compiler during leak sanitizer builds." FORCE)
5871
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C++ compiler during leak sanitizer builds." FORCE)
5972
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during leak sanitizer builds" FORCE)
60-
elseif(CPR_DEBUG_SANITIZER_FLAG_UB AND UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
61-
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during undefined behaviour sanitizer builds." FORCE)
62-
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during undefined behaviour sanitizer builds." FORCE)
63-
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during undefined behaviour sanitizer builds" FORCE)
64-
elseif(CPR_DEBUG_SANITIZER_FLAG_ALL AND ALL_SANITIZERS_AVAILABLE)
73+
elseif(UNDEFINED_BEHAVIOR_SANITIZER_AVAILABLE_AND_ENABLED)
74+
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during undefined behavior sanitizer builds." FORCE)
75+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during undefined behavior sanitizer builds." FORCE)
76+
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during undefined behavior sanitizer builds" FORCE)
77+
elseif(ALL_SANITIZERS_AVAILABLE_AND_ENABLED)
6578
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during most possible sanitizer builds." FORCE)
6679
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during most possible sanitizer builds." FORCE)
6780
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during most possible sanitizer builds" FORCE)

test/multiasync_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ TEST(AsyncWrapperNonCancellableTests, TestExceptionsNoSharedState) {
4545
ASSERT_FALSE(test_wrapper.valid());
4646

4747
// Trying to get or wait for a future that doesn't have a shared state should result to an exception
48-
// It should be noted that there is a divergence from std::future behavior here: calling wait* on the original std::future is undefined behaviour, according to cppreference.com . We find it preferrable to throw an exception.
48+
// It should be noted that there is a divergence from std::future behavior here: calling wait* on the original std::future is undefined behavior, according to cppreference.com . We find it preferrable to throw an exception.
4949
EXPECT_THROW(std::ignore = test_wrapper.get(), std::exception);
5050
EXPECT_THROW(test_wrapper.wait(), std::exception);
5151
EXPECT_THROW(test_wrapper.wait_for(five_secs), std::exception);
@@ -401,7 +401,7 @@ TEST(MultiAsyncCancelTests, TestCancellationOnResponseWrapperDestruction) {
401401
* the user can realistically expect to have their request cancelled within
402402
* ~1s on a bad case (low network speed).
403403
* INFO this test is not, strictly speaking, deterministic. It depends at the
404-
* least on scheduler behaviour. We have tried, however, to set a boundary that
404+
* least on scheduler behavior. We have tried, however, to set a boundary that
405405
* is permissive enough to ensure consistency.
406406
*/
407407

0 commit comments

Comments
 (0)