aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEnrico Seiler <eseiler@users.noreply.github.com>2023-07-05 19:05:08 +0200
committerGitHub <noreply@github.com>2023-07-05 18:05:08 +0100
commite730f91d8cb6af19a172d6a36b4279181a02a9ff (patch)
tree3df9b3f796f444fa2cb1bb7030b207f79bffcd80
parent43b2917dce1ae9c5949d66dfc6baf8d04d359971 (diff)
downloadgoogle-benchmark-e730f91d8cb6af19a172d6a36b4279181a02a9ff.tar.gz
Fix passing non-const lvalue refs to DoNotOptimize (#1622)
-rw-r--r--cmake/GoogleTest.cmake20
-rw-r--r--include/benchmark/benchmark.h44
-rw-r--r--test/CMakeLists.txt5
3 files changed, 51 insertions, 18 deletions
diff --git a/cmake/GoogleTest.cmake b/cmake/GoogleTest.cmake
index 44adbfb..e66e9d1 100644
--- a/cmake/GoogleTest.cmake
+++ b/cmake/GoogleTest.cmake
@@ -29,19 +29,25 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
include(${GOOGLETEST_PREFIX}/googletest-paths.cmake)
-# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.
-if (MSVC)
- add_compile_options(/wd4244 /wd4722)
-else()
- add_compile_options(-w)
-endif()
-
# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${GOOGLETEST_SOURCE_DIR}
${GOOGLETEST_BINARY_DIR}
EXCLUDE_FROM_ALL)
+# googletest doesn't seem to want to stay build warning clean so let's not hurt ourselves.
+if (MSVC)
+ target_compile_options(gtest PRIVATE "/wd4244" "/wd4722")
+ target_compile_options(gtest_main PRIVATE "/wd4244" "/wd4722")
+ target_compile_options(gmock PRIVATE "/wd4244" "/wd4722")
+ target_compile_options(gmock_main PRIVATE "/wd4244" "/wd4722")
+else()
+ target_compile_options(gtest PRIVATE "-w")
+ target_compile_options(gtest_main PRIVATE "-w")
+ target_compile_options(gmock PRIVATE "-w")
+ target_compile_options(gmock_main PRIVATE "-w")
+endif()
+
if(NOT DEFINED GTEST_COMPILE_COMMANDS)
set(GTEST_COMPILE_COMMANDS ON)
endif()
diff --git a/include/benchmark/benchmark.h b/include/benchmark/benchmark.h
index 1444ec6..e3857e7 100644
--- a/include/benchmark/benchmark.h
+++ b/include/benchmark/benchmark.h
@@ -465,19 +465,24 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
}
template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(
-#ifdef BENCHMARK_HAS_CXX11
- Tp&& value
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
+#if defined(__clang__)
+ asm volatile("" : "+r,m"(value) : : "memory");
#else
- Tp& value
+ asm volatile("" : "+m,r"(value) : : "memory");
#endif
-) {
+}
+
+#ifdef BENCHMARK_HAS_CXX11
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
#if defined(__clang__)
asm volatile("" : "+r,m"(value) : : "memory");
#else
asm volatile("" : "+m,r"(value) : : "memory");
#endif
}
+#endif
#elif defined(BENCHMARK_HAS_CXX11) && (__GNUC__ >= 5)
// Workaround for a bug with full argument copy overhead with GCC.
// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
@@ -507,6 +512,22 @@ template <class Tp>
inline BENCHMARK_ALWAYS_INLINE
typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
(sizeof(Tp) <= sizeof(Tp*))>::type
+ DoNotOptimize(Tp& value) {
+ asm volatile("" : "+m,r"(value) : : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+ typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
+ (sizeof(Tp) > sizeof(Tp*))>::type
+ DoNotOptimize(Tp& value) {
+ asm volatile("" : "+m"(value) : : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+ typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
+ (sizeof(Tp) <= sizeof(Tp*))>::type
DoNotOptimize(Tp&& value) {
asm volatile("" : "+m,r"(value) : : "memory");
}
@@ -532,16 +553,17 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
}
template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
+ asm volatile("" : "+m"(value) : : "memory");
+}
+
#ifdef BENCHMARK_HAS_CXX11
- Tp&& value
-#else
- Tp& value
-#endif
-) {
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
asm volatile("" : "+m"(value) : : "memory");
}
#endif
+#endif
#ifndef BENCHMARK_HAS_CXX11
inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 78d6d51..fd88131 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -122,6 +122,11 @@ compile_benchmark_test(skip_with_error_test)
add_test(NAME skip_with_error_test COMMAND skip_with_error_test --benchmark_min_time=0.01s)
compile_benchmark_test(donotoptimize_test)
+# Enable errors for deprecated deprecations (DoNotOptimize(Tp const& value)).
+check_cxx_compiler_flag(-Werror=deprecated-declarations BENCHMARK_HAS_DEPRECATED_DECLARATIONS_FLAG)
+if (BENCHMARK_HAS_DEPRECATED_DECLARATIONS_FLAG)
+ target_compile_options (donotoptimize_test PRIVATE "-Werror=deprecated-declarations")
+endif()
# Some of the issues with DoNotOptimize only occur when optimization is enabled
check_cxx_compiler_flag(-O3 BENCHMARK_HAS_O3_FLAG)
if (BENCHMARK_HAS_O3_FLAG)