Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
b6cd4052
Commit
b6cd4052
authored
Jan 04, 2019
by
Abseil Team
Committed by
gennadiycivil
Jan 07, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Googletest export
Fix GTEST_IS_NULL_LITERAL_ for types that have magic implicit conversions. PiperOrigin-RevId: 227879345
parent
3880b13e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
7 deletions
+44
-7
gtest-internal.h
googletest/include/gtest/internal/gtest-internal.h
+21
-4
gtest_unittest.cc
googletest/test/gtest_unittest.cc
+23
-3
No files found.
googletest/include/gtest/internal/gtest-internal.h
View file @
b6cd4052
...
@@ -58,6 +58,7 @@
...
@@ -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[];
...
@@ -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 {
...
@@ -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
(
...
...
googletest/test/gtest_unittest.cc
View file @
b6cd4052
...
@@ -519,9 +519,9 @@ TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) {
...
@@ -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) {
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment