Googletest export
Fix GTEST_IS_NULL_LITERAL_ for types that have magic implicit conversions. PiperOrigin-RevId: 227879345
This commit is contained in:
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user