Googletest export
Fix GTEST_IS_NULL_LITERAL_ for types that have magic implicit conversions. PiperOrigin-RevId: 227879345
This commit is contained in:
		
				
					committed by
					
						
						gennadiycivil
					
				
			
			
				
	
			
			
			
						parent
						
							3880b13e4c
						
					
				
				
					commit
					b6cd405286
				
			@@ -58,6 +58,7 @@
 | 
				
			|||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#include <set>
 | 
					#include <set>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <type_traits>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "gtest/gtest-message.h"
 | 
					#include "gtest/gtest-message.h"
 | 
				
			||||||
@@ -108,16 +109,29 @@ GTEST_API_ extern const char kStackTraceMarker[];
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// An IgnoredValue object can be implicitly constructed from ANY value.
 | 
					// An IgnoredValue object can be implicitly constructed from ANY value.
 | 
				
			||||||
class IgnoredValue {
 | 
					class IgnoredValue {
 | 
				
			||||||
 | 
					  struct Sink {};
 | 
				
			||||||
 public:
 | 
					 public:
 | 
				
			||||||
  // This constructor template allows any value to be implicitly
 | 
					  // This constructor template allows any value to be implicitly
 | 
				
			||||||
  // converted to IgnoredValue.  The object has no data member and
 | 
					  // converted to IgnoredValue.  The object has no data member and
 | 
				
			||||||
  // doesn't try to remember anything about the argument.  We
 | 
					  // doesn't try to remember anything about the argument.  We
 | 
				
			||||||
  // deliberately omit the 'explicit' keyword in order to allow the
 | 
					  // deliberately omit the 'explicit' keyword in order to allow the
 | 
				
			||||||
  // conversion to be implicit.
 | 
					  // conversion to be implicit.
 | 
				
			||||||
  template <typename T>
 | 
					  // Disable the conversion if T already has a magical conversion operator.
 | 
				
			||||||
 | 
					  // Otherwise we get ambiguity.
 | 
				
			||||||
 | 
					  template <typename T,
 | 
				
			||||||
 | 
					            typename std::enable_if<!std::is_convertible<T, Sink>::value,
 | 
				
			||||||
 | 
					                                    int>::type = 0>
 | 
				
			||||||
  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)
 | 
					  IgnoredValue(const T& /* ignored */) {}  // NOLINT(runtime/explicit)
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The only type that should be convertible to Secret* is nullptr.
 | 
				
			||||||
 | 
					// The other null pointer constants are not of a type that is convertible to
 | 
				
			||||||
 | 
					// Secret*. Only the literal with the right value is.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					using TypeIsValidNullptrConstant = std::integral_constant<
 | 
				
			||||||
 | 
					    bool, std::is_same<typename std::decay<T>::type, std::nullptr_t>::value ||
 | 
				
			||||||
 | 
					              !std::is_convertible<T, Secret*>::value>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Two overloaded helpers for checking at compile time whether an
 | 
					// Two overloaded helpers for checking at compile time whether an
 | 
				
			||||||
// expression is a null pointer literal (i.e. NULL or any 0-valued
 | 
					// expression is a null pointer literal (i.e. NULL or any 0-valued
 | 
				
			||||||
// compile-time integral constant).  These helpers have no
 | 
					// compile-time integral constant).  These helpers have no
 | 
				
			||||||
@@ -130,13 +144,16 @@ class IgnoredValue {
 | 
				
			|||||||
// a null pointer literal.  Therefore, we know that x is a null
 | 
					// a null pointer literal.  Therefore, we know that x is a null
 | 
				
			||||||
// pointer literal if and only if the first version is picked by the
 | 
					// pointer literal if and only if the first version is picked by the
 | 
				
			||||||
// compiler.
 | 
					// compiler.
 | 
				
			||||||
std::true_type IsNullLiteralHelper(Secret*);
 | 
					std::true_type IsNullLiteralHelper(Secret*, std::true_type);
 | 
				
			||||||
std::false_type IsNullLiteralHelper(IgnoredValue);
 | 
					std::false_type IsNullLiteralHelper(IgnoredValue, std::false_type);
 | 
				
			||||||
 | 
					std::false_type IsNullLiteralHelper(IgnoredValue, std::true_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A compile-time bool constant that is true if and only if x is a null pointer
 | 
					// A compile-time bool constant that is true if and only if x is a null pointer
 | 
				
			||||||
// literal (i.e. nullptr, NULL or any 0-valued compile-time integral constant).
 | 
					// literal (i.e. nullptr, NULL or any 0-valued compile-time integral constant).
 | 
				
			||||||
#define GTEST_IS_NULL_LITERAL_(x) \
 | 
					#define GTEST_IS_NULL_LITERAL_(x)                    \
 | 
				
			||||||
  decltype(::testing::internal::IsNullLiteralHelper(x))::value
 | 
					  decltype(::testing::internal::IsNullLiteralHelper( \
 | 
				
			||||||
 | 
					      x,                                             \
 | 
				
			||||||
 | 
					      ::testing::internal::TypeIsValidNullptrConstant<decltype(x)>()))::value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Appends the user-supplied message to the Google-Test-generated message.
 | 
					// Appends the user-supplied message to the Google-Test-generated message.
 | 
				
			||||||
GTEST_API_ std::string AppendUserMessage(
 | 
					GTEST_API_ std::string AppendUserMessage(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -519,9 +519,9 @@ TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) {
 | 
				
			|||||||
// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null
 | 
					// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null
 | 
				
			||||||
// pointer literal.
 | 
					// pointer literal.
 | 
				
			||||||
TEST(NullLiteralTest, IsTrueForNullLiterals) {
 | 
					TEST(NullLiteralTest, IsTrueForNullLiterals) {
 | 
				
			||||||
  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(nullptr));
 | 
					  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL));  // NOLINT
 | 
				
			||||||
  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(nullptr));
 | 
					  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0));     // NOLINT
 | 
				
			||||||
  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(nullptr));
 | 
					  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0u));    // NOLINT
 | 
				
			||||||
  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(nullptr));
 | 
					  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(nullptr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -534,6 +534,26 @@ TEST(NullLiteralTest, IsFalseForNonNullLiterals) {
 | 
				
			|||||||
  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast<void*>(nullptr)));
 | 
					  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast<void*>(nullptr)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ConvertToAll {
 | 
				
			||||||
 | 
					  template <typename T>
 | 
				
			||||||
 | 
					  operator T() const {  // NOLINT
 | 
				
			||||||
 | 
					    return T();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ConvertToAllButNoPointers {
 | 
				
			||||||
 | 
					  template <typename T,
 | 
				
			||||||
 | 
					            typename std::enable_if<!std::is_pointer<T>::value, int>::type = 0>
 | 
				
			||||||
 | 
					  operator T() const {  // NOLINT
 | 
				
			||||||
 | 
					    return T();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(NullLiteralTest, ImplicitConversion) {
 | 
				
			||||||
 | 
					  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(ConvertToAll{}));
 | 
				
			||||||
 | 
					  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(ConvertToAllButNoPointers{}));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ifdef __BORLANDC__
 | 
					# ifdef __BORLANDC__
 | 
				
			||||||
// Restores warnings after previous "#pragma option push" suppressed them.
 | 
					// Restores warnings after previous "#pragma option push" suppressed them.
 | 
				
			||||||
#  pragma option pop
 | 
					#  pragma option pop
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user