Skip to content

Commit

Permalink
Fix passing non-const lvalue refs to DoNotOptimize (#1622)
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler authored Jul 5, 2023
1 parent 43b2917 commit e730f91
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 18 deletions.
20 changes: 13 additions & 7 deletions cmake/GoogleTest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
44 changes: 33 additions & 11 deletions include/benchmark/benchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -503,6 +508,22 @@ inline BENCHMARK_ALWAYS_INLINE
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");
}

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 &&
Expand Down Expand Up @@ -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() {
Expand Down
5 changes: 5 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit e730f91

Please sign in to comment.