Avod exit-time destructors in macros when possible

This change attemps to reduce the introduction of exit-time destructors
by gtest/gmock whenever it is possible, to just skip the destructor
during termination. This is useful for codebases that aim to comply with
clang's `-Wexit-time-destructors`. However, this change does not attempt
to make all of gtest/gmock complaint with this warning, but limits
itself to what merely affects user code.

Bug: https://github.com/google/googletest/issues/4803
This commit is contained in:
Claudio DeSouza 2025-07-21 12:02:08 +01:00
parent 7e17b15f15
commit 770390b31c
No known key found for this signature in database
4 changed files with 18 additions and 4 deletions

View File

@ -111,7 +111,8 @@
static_assert(true, "no-op to require trailing semicolon")
#define GMOCK_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \
GTEST_API_ GMOCK_NODESTRUCTOR \
::std::string GMOCK_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")

View File

@ -256,8 +256,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together.
#define TYPED_TEST_SUITE_P(SuiteName) \
static ::testing::internal::TypedTestSuitePState \
#define TYPED_TEST_SUITE_P(SuiteName) \
GTEST_NODESTRUCTOR static ::testing::internal::TypedTestSuitePState \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
// Legacy API is deprecated but still available

View File

@ -1514,4 +1514,10 @@ class NeverThrown {
test_suite_name, test_name)>); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#ifdef __clang__
#define GTEST_NODESTRUCTOR [[clang::no_destroy]]
#else
#define GTEST_NODESTRUCTOR
#endif
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_

View File

@ -2229,6 +2229,12 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
#define GTEST_FLAG(name) FLAGS_gtest_##name
#endif // !defined(GTEST_FLAG)
#ifdef __clang__
#define GMOCK_NODESTRUCTOR [[clang::no_destroy]]
#else
#define GMOCK_NODESTRUCTOR
#endif
// Pick a command line flags implementation.
#ifdef GTEST_INTERNAL_HAS_ABSL_FLAGS
@ -2271,7 +2277,8 @@ using TimeInMillis = int64_t; // Represents time in milliseconds.
static_assert(true, "no-op to require trailing semicolon")
#define GTEST_DEFINE_string_(name, default_val, doc) \
namespace testing { \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val); \
GTEST_API_ GTEST_NODESTRUCTOR \
::std::string GTEST_FLAG(name) = (default_val); \
} \
static_assert(true, "no-op to require trailing semicolon")