Use `[[maybe_unused]]` when it is available to avoid
-Wused-but-marked-unused warnings

PiperOrigin-RevId: 625430612
Change-Id: Ia9d2e47984e1e6f91966afae8a6750119ae69446
diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h
index 7e17b30..cd12996 100644
--- a/googlemock/include/gmock/gmock-actions.h
+++ b/googlemock/include/gmock/gmock-actions.h
@@ -2174,9 +2174,9 @@
 }
 
 #define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \
-  , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_
-#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                 \
-  const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \
+  , GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const arg##i##_type& arg##i
+#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_                               \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED const args_type& args GMOCK_PP_REPEAT( \
       GMOCK_INTERNAL_ARG_UNUSED, , 10)
 
 #define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index 6b6b437..33a6716 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -5445,47 +5445,47 @@
       ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
 
 // MATCHER* macros itself are listed below.
-#define MATCHER(name, description)                                             \
-  class name##Matcher                                                          \
-      : public ::testing::internal::MatcherBaseImpl<name##Matcher> {           \
-   public:                                                                     \
-    template <typename arg_type>                                               \
-    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {   \
-     public:                                                                   \
-      gmock_Impl() {}                                                          \
-      bool MatchAndExplain(                                                    \
-          const arg_type& arg,                                                 \
-          ::testing::MatchResultListener* result_listener) const override;     \
-      void DescribeTo(::std::ostream* gmock_os) const override {               \
-        *gmock_os << FormatDescription(false);                                 \
-      }                                                                        \
-      void DescribeNegationTo(::std::ostream* gmock_os) const override {       \
-        *gmock_os << FormatDescription(true);                                  \
-      }                                                                        \
-                                                                               \
-     private:                                                                  \
-      ::std::string FormatDescription(bool negation) const {                   \
-        /* NOLINTNEXTLINE readability-redundant-string-init */                 \
-        ::std::string gmock_description = (description);                       \
-        if (!gmock_description.empty()) {                                      \
-          return gmock_description;                                            \
-        }                                                                      \
-        return ::testing::internal::FormatMatcherDescription(negation, #name,  \
-                                                             {}, {});          \
-      }                                                                        \
-    };                                                                         \
-  };                                                                           \
-  inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH()                           \
-      GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function")               \
-          GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function")    \
-              name GMOCK_INTERNAL_WARNING_POP()() {                            \
-    return {};                                                                 \
-  }                                                                            \
-  template <typename arg_type>                                                 \
-  bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(                   \
-      const arg_type& arg,                                                     \
-      ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \
-      const
+#define MATCHER(name, description)                                            \
+  class name##Matcher                                                         \
+      : public ::testing::internal::MatcherBaseImpl<name##Matcher> {          \
+   public:                                                                    \
+    template <typename arg_type>                                              \
+    class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> {  \
+     public:                                                                  \
+      gmock_Impl() {}                                                         \
+      bool MatchAndExplain(                                                   \
+          const arg_type& arg,                                                \
+          ::testing::MatchResultListener* result_listener) const override;    \
+      void DescribeTo(::std::ostream* gmock_os) const override {              \
+        *gmock_os << FormatDescription(false);                                \
+      }                                                                       \
+      void DescribeNegationTo(::std::ostream* gmock_os) const override {      \
+        *gmock_os << FormatDescription(true);                                 \
+      }                                                                       \
+                                                                              \
+     private:                                                                 \
+      ::std::string FormatDescription(bool negation) const {                  \
+        /* NOLINTNEXTLINE readability-redundant-string-init */                \
+        ::std::string gmock_description = (description);                      \
+        if (!gmock_description.empty()) {                                     \
+          return gmock_description;                                           \
+        }                                                                     \
+        return ::testing::internal::FormatMatcherDescription(negation, #name, \
+                                                             {}, {});         \
+      }                                                                       \
+    };                                                                        \
+  };                                                                          \
+  inline name##Matcher GMOCK_INTERNAL_WARNING_PUSH()                          \
+      GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-function")              \
+          GMOCK_INTERNAL_WARNING_CLANG(ignored, "-Wunused-member-function")   \
+              name GMOCK_INTERNAL_WARNING_POP()() {                           \
+    return {};                                                                \
+  }                                                                           \
+  template <typename arg_type>                                                \
+  bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(                  \
+      const arg_type& arg,                                                    \
+      GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::MatchResultListener*   \
+          result_listener) const
 
 #define MATCHER_P(name, p0, description) \
   GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0))
@@ -5567,11 +5567,11 @@
   }                                                                            \
   template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)>                      \
   template <typename arg_type>                                                 \
-  bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl<        \
-      arg_type>::MatchAndExplain(const arg_type& arg,                          \
-                                 ::testing::MatchResultListener*               \
-                                     result_listener GTEST_ATTRIBUTE_UNUSED_)  \
-      const
+  bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::                   \
+      gmock_Impl<arg_type>::MatchAndExplain(                                   \
+          const arg_type& arg,                                                 \
+          GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED ::testing::                    \
+              MatchResultListener* result_listener) const
 
 #define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \
   GMOCK_PP_TAIL(                                     \
diff --git a/googletest/include/gtest/gtest-param-test.h b/googletest/include/gtest/gtest-param-test.h
index 49a47ea..6847b64 100644
--- a/googletest/include/gtest/gtest-param-test.h
+++ b/googletest/include/gtest/gtest-param-test.h
@@ -469,7 +469,7 @@
               ::testing::internal::CodeLocation(__FILE__, __LINE__));          \
       return 0;                                                                \
     }                                                                          \
-    static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_;               \
+    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int gtest_registering_dummy_; \
   };                                                                           \
   int GTEST_TEST_CLASS_NAME_(test_suite_name,                                  \
                              test_name)::gtest_registering_dummy_ =            \
@@ -514,8 +514,8 @@
         ::testing::internal::DefaultParamName<test_suite_name::ParamType>,   \
         DUMMY_PARAM_))))(info);                                              \
   }                                                                          \
-  static int gtest_##prefix##test_suite_name##_dummy_                        \
-      GTEST_ATTRIBUTE_UNUSED_ =                                              \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static int                           \
+      gtest_##prefix##test_suite_name##_dummy_ =                             \
           ::testing::UnitTest::GetInstance()                                 \
               ->parameterized_test_registry()                                \
               .GetTestSuitePatternHolder<test_suite_name>(                   \
diff --git a/googletest/include/gtest/gtest-typed-test.h b/googletest/include/gtest/gtest-typed-test.h
index 72de536..305b0b5 100644
--- a/googletest/include/gtest/gtest-typed-test.h
+++ b/googletest/include/gtest/gtest-typed-test.h
@@ -194,33 +194,34 @@
   typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
   GTEST_NAME_GENERATOR_(CaseName)
 
-#define TYPED_TEST(CaseName, TestName)                                        \
-  static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1,                       \
-                "test-name must not be empty");                               \
-  template <typename gtest_TypeParam_>                                        \
-  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                            \
-      : public CaseName<gtest_TypeParam_> {                                   \
-   private:                                                                   \
-    typedef CaseName<gtest_TypeParam_> TestFixture;                           \
-    typedef gtest_TypeParam_ TypeParam;                                       \
-    void TestBody() override;                                                 \
-  };                                                                          \
-  static bool gtest_##CaseName##_##TestName##_registered_                     \
-      GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest<   \
-          CaseName,                                                           \
-          ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName,   \
-                                                                  TestName)>, \
-          GTEST_TYPE_PARAMS_(                                                 \
-              CaseName)>::Register("",                                        \
-                                   ::testing::internal::CodeLocation(         \
-                                       __FILE__, __LINE__),                   \
-                                   GTEST_STRINGIFY_(CaseName),                \
-                                   GTEST_STRINGIFY_(TestName), 0,             \
-                                   ::testing::internal::GenerateNames<        \
-                                       GTEST_NAME_GENERATOR_(CaseName),       \
-                                       GTEST_TYPE_PARAMS_(CaseName)>());      \
-  template <typename gtest_TypeParam_>                                        \
-  void GTEST_TEST_CLASS_NAME_(CaseName,                                       \
+#define TYPED_TEST(CaseName, TestName)                                       \
+  static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1,                      \
+                "test-name must not be empty");                              \
+  template <typename gtest_TypeParam_>                                       \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                           \
+      : public CaseName<gtest_TypeParam_> {                                  \
+   private:                                                                  \
+    typedef CaseName<gtest_TypeParam_> TestFixture;                          \
+    typedef gtest_TypeParam_ TypeParam;                                      \
+    void TestBody() override;                                                \
+  };                                                                         \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \
+      gtest_##CaseName##_##TestName##_registered_ =                          \
+          ::testing::internal::TypeParameterizedTest<                        \
+              CaseName,                                                      \
+              ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(       \
+                  CaseName, TestName)>,                                      \
+              GTEST_TYPE_PARAMS_(                                            \
+                  CaseName)>::Register("",                                   \
+                                       ::testing::internal::CodeLocation(    \
+                                           __FILE__, __LINE__),              \
+                                       GTEST_STRINGIFY_(CaseName),           \
+                                       GTEST_STRINGIFY_(TestName), 0,        \
+                                       ::testing::internal::GenerateNames<   \
+                                           GTEST_NAME_GENERATOR_(CaseName),  \
+                                           GTEST_TYPE_PARAMS_(CaseName)>()); \
+  template <typename gtest_TypeParam_>                                       \
+  void GTEST_TEST_CLASS_NAME_(CaseName,                                      \
                               TestName)<gtest_TypeParam_>::TestBody()
 
 // Legacy API is deprecated but still available
@@ -267,22 +268,23 @@
   TYPED_TEST_SUITE_P
 #endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
-#define TYPED_TEST_P(SuiteName, TestName)                           \
-  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                     \
-  template <typename gtest_TypeParam_>                              \
-  class TestName : public SuiteName<gtest_TypeParam_> {             \
-   private:                                                         \
-    typedef SuiteName<gtest_TypeParam_> TestFixture;                \
-    typedef gtest_TypeParam_ TypeParam;                             \
-    void TestBody() override;                                       \
-  };                                                                \
-  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
-      GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName(       \
-          __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName),          \
-          GTEST_STRINGIFY_(TestName));                              \
-  }                                                                 \
-  template <typename gtest_TypeParam_>                              \
-  void GTEST_SUITE_NAMESPACE_(                                      \
+#define TYPED_TEST_P(SuiteName, TestName)                         \
+  namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                   \
+  template <typename gtest_TypeParam_>                            \
+  class TestName : public SuiteName<gtest_TypeParam_> {           \
+   private:                                                       \
+    typedef SuiteName<gtest_TypeParam_> TestFixture;              \
+    typedef gtest_TypeParam_ TypeParam;                           \
+    void TestBody() override;                                     \
+  };                                                              \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool               \
+      gtest_##TestName##_defined_ =                               \
+          GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
+              __FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName),    \
+              GTEST_STRINGIFY_(TestName));                        \
+  }                                                               \
+  template <typename gtest_TypeParam_>                            \
+  void GTEST_SUITE_NAMESPACE_(                                    \
       SuiteName)::TestName<gtest_TypeParam_>::TestBody()
 
 // Note: this won't work correctly if the trailing arguments are macros.
@@ -290,8 +292,8 @@
   namespace GTEST_SUITE_NAMESPACE_(SuiteName) {                             \
   typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_;      \
   }                                                                         \
-  static const char* const GTEST_REGISTERED_TEST_NAMES_(                    \
-      SuiteName) GTEST_ATTRIBUTE_UNUSED_ =                                  \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static const char* const            \
+  GTEST_REGISTERED_TEST_NAMES_(SuiteName) =                                 \
       GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
           GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
 
@@ -303,22 +305,24 @@
   REGISTER_TYPED_TEST_SUITE_P
 #endif  // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
 
-#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)     \
-  static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1,                     \
-                "test-suit-prefix must not be empty");                    \
-  static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ =      \
-      ::testing::internal::TypeParameterizedTestSuite<                    \
-          SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_,  \
-          ::testing::internal::GenerateTypeList<Types>::type>::           \
-          Register(GTEST_STRINGIFY_(Prefix),                              \
-                   ::testing::internal::CodeLocation(__FILE__, __LINE__), \
-                   &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName),           \
-                   GTEST_STRINGIFY_(SuiteName),                           \
-                   GTEST_REGISTERED_TEST_NAMES_(SuiteName),               \
-                   ::testing::internal::GenerateNames<                    \
-                       ::testing::internal::NameGeneratorSelector<        \
-                           __VA_ARGS__>::type,                            \
-                       ::testing::internal::GenerateTypeList<Types>::type>())
+#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)        \
+  static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1,                        \
+                "test-suit-prefix must not be empty");                       \
+  GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool                          \
+      gtest_##Prefix##_##SuiteName =                                         \
+          ::testing::internal::TypeParameterizedTestSuite<                   \
+              SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
+              ::testing::internal::GenerateTypeList<Types>::type>::          \
+              Register(                                                      \
+                  GTEST_STRINGIFY_(Prefix),                                  \
+                  ::testing::internal::CodeLocation(__FILE__, __LINE__),     \
+                  &GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName),               \
+                  GTEST_STRINGIFY_(SuiteName),                               \
+                  GTEST_REGISTERED_TEST_NAMES_(SuiteName),                   \
+                  ::testing::internal::GenerateNames<                        \
+                      ::testing::internal::NameGeneratorSelector<            \
+                          __VA_ARGS__>::type,                                \
+                      ::testing::internal::GenerateTypeList<Types>::type>())
 
 // Legacy API is deprecated but still available
 #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h
index cffb8e1..7e55dc6 100644
--- a/googletest/include/gtest/internal/gtest-internal.h
+++ b/googletest/include/gtest/internal/gtest-internal.h
@@ -1501,7 +1501,8 @@
                                                                                \
    private:                                                                    \
     void TestBody() override;                                                  \
-    static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;      \
+    GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static ::testing::TestInfo* const    \
+        test_info_;                                                            \
   };                                                                           \
                                                                                \
   ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,           \
diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h
index 6c469e9..4f0d89d 100644
--- a/googletest/include/gtest/internal/gtest-port.h
+++ b/googletest/include/gtest/internal/gtest-port.h
@@ -194,8 +194,6 @@
 //
 // Macros for basic C++ coding:
 //   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
-//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a
-//                              variable don't have to be used.
 //   GTEST_MUST_USE_RESULT_   - declares that a function's result must be used.
 //   GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is
 //                                        suppressed (constant conditional).
@@ -749,6 +747,20 @@
 #define GTEST_HAVE_ATTRIBUTE_(x) 0
 #endif
 
+// GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE
+//
+// A function-like feature checking macro that accepts C++11 style attributes.
+// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6
+// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't
+// find `__has_cpp_attribute`, will evaluate to 0.
+#if defined(__has_cpp_attribute)
+// NOTE: requiring __cplusplus above should not be necessary, but
+// works around https://bugs.llvm.org/show_bug.cgi?id=23435.
+#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+#define GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(x) 0
+#endif
+
 // GTEST_HAVE_FEATURE_
 //
 // A function-like feature checking macro that is a wrapper around
@@ -760,14 +772,22 @@
 #endif
 
 // Use this annotation after a variable or parameter declaration to tell the
-// compiler the variable/parameter does not have to be used.
+// compiler the variable/parameter may be used.
 // Example:
 //
-//   GTEST_ATTRIBUTE_UNUSED_ int foo = bar();
-#if GTEST_HAVE_ATTRIBUTE_(unused)
-#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused))
+//   GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED int foo = bar();
+//
+// This can be removed once we only support only C++17 or newer and
+// [[maybe_unused]] is available on all supported platforms.
+#if GTEST_INTERNAL_HAVE_CPP_ATTRIBUTE(maybe_unused)
+#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED [[maybe_unused]]
+#elif GTEST_HAVE_ATTRIBUTE_(unused)
+// This is inferior to [[maybe_unused]] as it can produce a
+// -Wused-but-marked-unused warning on optionally used symbols, but it is all we
+// have.
+#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED __attribute__((__unused__))
 #else
-#define GTEST_ATTRIBUTE_UNUSED_
+#define GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED
 #endif
 
 // Use this annotation before a function that takes a printf format string.
diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc
index edbe2ea..5ded865 100644
--- a/googletest/test/gtest_unittest.cc
+++ b/googletest/test/gtest_unittest.cc
@@ -2163,7 +2163,7 @@
 };
 
 // This will test property recording outside of any test or test case.
-static Environment* record_property_env GTEST_ATTRIBUTE_UNUSED_ =
+GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static Environment* record_property_env =
     AddGlobalTestEnvironment(new UnitTestRecordPropertyTestEnvironment);
 
 // This group of tests is for predicate assertions (ASSERT_PRED*, etc)
@@ -6705,8 +6705,9 @@
 
 // Verifies that StaticAssertTypeEq works in a namespace scope.
 
-static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq<bool, bool>();
-static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ =
+GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool dummy1 =
+    StaticAssertTypeEq<bool, bool>();
+GTEST_INTERNAL_ATTRIBUTE_MAYBE_UNUSED static bool dummy2 =
     StaticAssertTypeEq<const int, const int>();
 
 // Verifies that StaticAssertTypeEq works in a class.