Fixes GCC 4.6 warnings (patch by Jeffrey Yasskin).


git-svn-id: http://googletest.googlecode.com/svn/trunk@531 861a406c-534a-0410-8894-cb66d6ee9925
diff --git a/include/gtest/gtest-typed-test.h b/include/gtest/gtest-typed-test.h
index eb6b0b8..2d3b8bf 100644
--- a/include/gtest/gtest-typed-test.h
+++ b/include/gtest/gtest-typed-test.h
@@ -175,7 +175,7 @@
     typedef gtest_TypeParam_ TypeParam; \
     virtual void TestBody(); \
   }; \
-  bool gtest_##CaseName##_##TestName##_registered_ = \
+  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
       ::testing::internal::TypeParameterizedTest< \
           CaseName, \
           ::testing::internal::TemplateSel< \
@@ -229,7 +229,7 @@
     typedef gtest_TypeParam_ TypeParam; \
     virtual void TestBody(); \
   }; \
-  static bool gtest_##TestName##_defined_ = \
+  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
           __FILE__, __LINE__, #CaseName, #TestName); \
   } \
@@ -248,7 +248,7 @@
 // since some compilers may choke on '>>' when passing a template
 // instance (e.g. Types<int>)
 #define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
-  bool gtest_##Prefix##_##CaseName = \
+  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
       ::testing::internal::TypeParameterizedTestCase<CaseName, \
           GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
           ::testing::internal::TypeList< Types >::type>::Register(\
diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h
index f7ed948..79e604c 100644
--- a/include/gtest/gtest.h
+++ b/include/gtest/gtest.h
@@ -1342,7 +1342,7 @@
 };
 
 // This specialization is used when the first argument to ASSERT_EQ()
-// is a null pointer literal.
+// is a null pointer literal, like NULL, false, or 0.
 template <>
 class EqHelper<true> {
  public:
@@ -1351,24 +1351,38 @@
   // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
   // EXPECT_EQ(false, a_bool).
   template <typename T1, typename T2>
-  static AssertionResult Compare(const char* expected_expression,
-                                 const char* actual_expression,
-                                 const T1& expected,
-                                 const T2& actual) {
+  static AssertionResult Compare(
+      const char* expected_expression,
+      const char* actual_expression,
+      const T1& expected,
+      const T2& actual,
+      // The following line prevents this overload from being considered if T2
+      // is not a pointer type.  We need this because ASSERT_EQ(NULL, my_ptr)
+      // expands to Compare("", "", NULL, my_ptr), which requires a conversion
+      // to match the Secret* in the other overload, which would otherwise make
+      // this template match better.
+      typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
     return CmpHelperEQ(expected_expression, actual_expression, expected,
                        actual);
   }
 
-  // This version will be picked when the second argument to
-  // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer).
-  template <typename T1, typename T2>
-  static AssertionResult Compare(const char* expected_expression,
-                                 const char* actual_expression,
-                                 const T1& /* expected */,
-                                 T2* actual) {
+  // This version will be picked when the second argument to ASSERT_EQ() is a
+  // pointer, e.g. ASSERT_EQ(NULL, a_pointer).
+  template <typename T>
+  static AssertionResult Compare(
+      const char* expected_expression,
+      const char* actual_expression,
+      // We used to have a second template parameter instead of Secret*.  That
+      // template parameter would deduce to 'long', making this a better match
+      // than the first overload even without the first overload's EnableIf.
+      // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to
+      // non-pointer argument" (even a deduced integral argument), so the old
+      // implementation caused warnings in user code.
+      Secret* /* expected (NULL) */,
+      T* actual) {
     // We already know that 'expected' is a null pointer.
     return CmpHelperEQ(expected_expression, actual_expression,
-                       static_cast<T2*>(NULL), actual);
+                       static_cast<T*>(NULL), actual);
   }
 };
 
diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h
index 3307855..2c08238 100644
--- a/include/gtest/internal/gtest-internal.h
+++ b/include/gtest/internal/gtest-internal.h
@@ -919,6 +919,13 @@
 template <class C>
 IsNotContainer IsContainerTest(...) { return '\0'; }
 
+// EnableIf<condition>::type is void when 'Cond' is true, and
+// undefined when 'Cond' is false.  To use SFINAE to make a function
+// overload only apply when a particular expression is true, add
+// "typename EnableIf<expression>::type* = 0" as the last parameter.
+template<bool> struct EnableIf;
+template<> struct EnableIf<true> { typedef void type; };  // NOLINT
+
 // Utilities for native arrays.
 
 // ArrayEq() compares two k-dimensional native arrays using the
@@ -1182,7 +1189,7 @@
   GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
  private:\
   virtual void TestBody();\
-  static ::testing::TestInfo* const test_info_;\
+  static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
   GTEST_DISALLOW_COPY_AND_ASSIGN_(\
       GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
 };\
diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc
index bf42d8b..db63ea9 100644
--- a/test/gtest-port_test.cc
+++ b/test/gtest-port_test.cc
@@ -168,6 +168,7 @@
 TEST(ImplicitCastTest, CanUseImplicitConstructor) {
   bool converted = false;
   To to = ::testing::internal::implicit_cast<To>(&converted);
+  (void)to;
   EXPECT_TRUE(converted);
 }
 
diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc
index 89a4a0e..1069ecf 100644
--- a/test/gtest_unittest.cc
+++ b/test/gtest_unittest.cc
@@ -322,13 +322,11 @@
   EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0));
   EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U));
   EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L));
-  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false));
 #ifndef __BORLANDC__
   // Some compilers may fail to detect some null pointer literals;
   // as long as users of the framework don't use such literals, this
   // is harmless.
   EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1));
-  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false));
 #endif
 }
 
@@ -3731,7 +3729,8 @@
 // compile.
 TEST(AssertionTest, AssertPrecedence) {
   ASSERT_EQ(1 < 2, true);
-  ASSERT_EQ(true && false, false);
+  bool false_value = false;
+  ASSERT_EQ(true && false_value, false);
 }
 
 // A subroutine used by the following test.
@@ -4220,7 +4219,7 @@
 TEST(ExpectTest, EXPECT_EQ_NULL) {
   // A success.
   const char* p = NULL;
-  // Some older GCC versions may issue a spurious waring in this or the next
+  // Some older GCC versions may issue a spurious warning in this or the next
   // assertion statement. This warning should not be suppressed with
   // static_cast since the test verifies the ability to use bare NULL as the
   // expected parameter to the macro.
@@ -4490,8 +4489,10 @@
 // Tests using bool values in {EXPECT|ASSERT}_EQ.
 TEST(EqAssertionTest, Bool) {
   EXPECT_EQ(true,  true);
-  EXPECT_FATAL_FAILURE(ASSERT_EQ(false, true),
-                       "Value of: true");
+  EXPECT_FATAL_FAILURE({
+      bool false_value = false;
+      ASSERT_EQ(false_value, true);
+    }, "Value of: true");
 }
 
 // Tests using int values in {EXPECT|ASSERT}_EQ.
@@ -6470,8 +6471,9 @@
 
 // Verifies that StaticAssertTypeEq works in a namespace scope.
 
-static bool dummy1 = StaticAssertTypeEq<bool, bool>();
-static bool dummy2 = StaticAssertTypeEq<const int, const int>();
+static bool dummy1 GTEST_ATTRIBUTE_UNUSED_ = StaticAssertTypeEq<bool, bool>();
+static bool dummy2 GTEST_ATTRIBUTE_UNUSED_ =
+    StaticAssertTypeEq<const int, const int>();
 
 // Verifies that StaticAssertTypeEq works in a class.