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
eabd5c90
Commit
eabd5c90
authored
Aug 24, 2017
by
Gennadiy Civil
Committed by
GitHub
Aug 24, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1186 from Dani-Hub/master
Prevent infinite loops for recursive containers like boost::filesystem::path
parents
c38baf98
87327b12
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
74 additions
and
8 deletions
+74
-8
gtest-printers.h
googletest/include/gtest/gtest-printers.h
+11
-8
gtest-internal.h
googletest/include/gtest/internal/gtest-internal.h
+25
-0
gtest-port.h
googletest/include/gtest/internal/gtest-port.h
+6
-0
gtest-printers_test.cc
googletest/test/gtest-printers_test.cc
+32
-0
No files found.
googletest/include/gtest/gtest-printers.h
View file @
eabd5c90
...
...
@@ -460,15 +460,17 @@ void PrintTo(const T& value, ::std::ostream* os) {
// DefaultPrintTo() is overloaded. The type of its first argument
// determines which version will be picked.
//
// Note that we check for
container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
// Note that we check for
recursive and other container types here, prior
//
to we check
for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
// that our format is used.
// that our format is used. To prevent an infinite runtime recursion
// during the output of recursive container types, we check first for
// those.
//
// Note that MSVC and clang-cl do allow an implicit conversion from
// pointer-to-function to pointer-to-object, but clang-cl warns on it.
...
...
@@ -477,16 +479,17 @@ void PrintTo(const T& value, ::std::ostream* os) {
// function pointers so that the `*os << p` in the object pointer overload
// doesn't cause that warning either.
DefaultPrintTo
(
WrapPrinterType
<
sizeof
(
IsContainerTest
<
T
>
(
0
))
==
sizeof
(
IsContainer
)
?
kPrintContainer
:
!
is_pointer
<
T
>::
value
?
kPrintOther
WrapPrinterType
<
(
sizeof
(
IsContainerTest
<
T
>
(
0
))
==
sizeof
(
IsContainer
))
&&
!
IsRecursiveContainer
<
T
>::
value
?
kPrintContainer
:
!
is_pointer
<
T
>::
value
?
kPrintOther
#if GTEST_LANG_CXX11
:
std
::
is_function
<
typename
std
::
remove_pointer
<
T
>::
type
>::
value
#else
:
!
internal
::
ImplicitlyConvertible
<
T
,
const
void
*>::
value
#endif
?
kPrintFunctionPointer
:
kPrintPointer
>
(),
?
kPrintFunctionPointer
:
kPrintPointer
>
(),
value
,
os
);
}
...
...
googletest/include/gtest/internal/gtest-internal.h
View file @
eabd5c90
...
...
@@ -940,6 +940,31 @@ typedef char IsNotContainer;
template
<
class
C
>
IsNotContainer
IsContainerTest
(
long
/* dummy */
)
{
return
'\0'
;
}
template
<
typename
C
,
bool
=
sizeof
(
IsContainerTest
<
C
>
(
0
))
==
sizeof
(
IsContainer
)
>
struct
IsRecursiveContainerImpl
;
template
<
typename
C
>
struct
IsRecursiveContainerImpl
<
C
,
false
>
:
public
false_type
{};
template
<
typename
C
>
struct
IsRecursiveContainerImpl
<
C
,
true
>
{
typedef
typename
IteratorTraits
<
typename
C
::
iterator
>::
value_type
value_type
;
typedef
is_same
<
value_type
,
C
>
type
;
};
// IsRecursiveContainer<Type> is a unary compile-time predicate that
// evaluates whether C is a recursive container type. A recursive container
// type is a container type whose value_type is equal to the container type
// itself. An example for a recursive container type is
// boost::filesystem::path, whose iterator has a value_type that is equal to
// boost::filesystem::path.
template
<
typename
C
>
struct
IsRecursiveContainer
:
public
IsRecursiveContainerImpl
<
C
>::
type
{};
// 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
...
...
googletest/include/gtest/internal/gtest-port.h
View file @
eabd5c90
...
...
@@ -2242,6 +2242,12 @@ template <bool bool_value> const bool bool_constant<bool_value>::value;
typedef
bool_constant
<
false
>
false_type
;
typedef
bool_constant
<
true
>
true_type
;
template
<
typename
T
,
typename
U
>
struct
is_same
:
public
false_type
{};
template
<
typename
T
>
struct
is_same
<
T
,
T
>
:
public
true_type
{};
template
<
typename
T
>
struct
is_pointer
:
public
false_type
{};
...
...
googletest/test/gtest-printers_test.cc
View file @
eabd5c90
...
...
@@ -187,6 +187,29 @@ inline ::std::ostream& operator<<(::std::ostream& os,
return
os
<<
"StreamableTemplateInFoo: "
<<
x
.
value
();
}
// A user-defined streamable but recursivly-defined container type in
// a user namespace, it mimics therefore std::filesystem::path or
// boost::filesystem::path.
class
PathLike
{
public
:
struct
iterator
{
typedef
PathLike
value_type
;
};
typedef
iterator
const_iterator
;
PathLike
()
{}
iterator
begin
()
const
{
return
iterator
();
}
iterator
end
()
const
{
return
iterator
();
}
friend
::
std
::
ostream
&
operator
<<
(
::
std
::
ostream
&
os
,
const
PathLike
&
)
{
return
os
<<
"Streamable-PathLike"
;
}
};
}
// namespace foo
namespace
testing
{
...
...
@@ -1161,6 +1184,15 @@ TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) {
Print
(
::
foo
::
StreamableTemplateInFoo
<
int
>
()));
}
// Tests printing a user-defined recursive container type that has a <<
// operator.
TEST
(
PrintStreamableTypeTest
,
PathLikeInUserNamespace
)
{
::
foo
::
PathLike
x
;
EXPECT_EQ
(
"Streamable-PathLike"
,
Print
(
x
));
const
::
foo
::
PathLike
cx
;
EXPECT_EQ
(
"Streamable-PathLike"
,
Print
(
cx
));
}
// Tests printing user-defined types that have a PrintTo() function.
TEST
(
PrintPrintableTypeTest
,
InUserNamespace
)
{
EXPECT_EQ
(
"PrintableViaPrintTo: 0"
,
...
...
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