mirror of
https://github.com/google/googletest.git
synced 2024-12-27 10:11:03 +08:00
Merge pull request #2527 from PiotrNycz:gmock_prevent_return_ref_to_store_temporaries_2
PiperOrigin-RevId: 277061341
This commit is contained in:
commit
b5fb5ba05c
@ -1052,6 +1052,10 @@ inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT
|
||||
return internal::ReturnRefAction<R>(x);
|
||||
}
|
||||
|
||||
// Prevent using ReturnRef on reference to temporary.
|
||||
template <typename R, R* = nullptr>
|
||||
internal::ReturnRefAction<R> ReturnRef(R&&) = delete;
|
||||
|
||||
// Creates an action that returns the reference to a copy of the
|
||||
// argument. The copy is created when the action is constructed and
|
||||
// lives as long as the action.
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -647,6 +648,41 @@ TEST(ReturnRefTest, IsCovariant) {
|
||||
EXPECT_EQ(&derived, &a.Perform(std::make_tuple()));
|
||||
}
|
||||
|
||||
template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))>
|
||||
bool CanCallReturnRef(T&&) { return true; }
|
||||
bool CanCallReturnRef(Unused) { return false; }
|
||||
|
||||
// Tests that ReturnRef(v) is working with non-temporaries (T&)
|
||||
TEST(ReturnRefTest, WorksForNonTemporary) {
|
||||
int scalar_value = 123;
|
||||
EXPECT_TRUE(CanCallReturnRef(scalar_value));
|
||||
|
||||
std::string non_scalar_value("ABC");
|
||||
EXPECT_TRUE(CanCallReturnRef(non_scalar_value));
|
||||
|
||||
const int const_scalar_value{321};
|
||||
EXPECT_TRUE(CanCallReturnRef(const_scalar_value));
|
||||
|
||||
const std::string const_non_scalar_value("CBA");
|
||||
EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value));
|
||||
}
|
||||
|
||||
// Tests that ReturnRef(v) is not working with temporaries (T&&)
|
||||
TEST(ReturnRefTest, DoesNotWorkForTemporary) {
|
||||
auto scalar_value = []() -> int { return 123; };
|
||||
EXPECT_FALSE(CanCallReturnRef(scalar_value()));
|
||||
|
||||
auto non_scalar_value = []() -> std::string { return "ABC"; };
|
||||
EXPECT_FALSE(CanCallReturnRef(non_scalar_value()));
|
||||
|
||||
// cannot use here callable returning "const scalar type",
|
||||
// because such const for scalar return type is ignored
|
||||
EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321)));
|
||||
|
||||
auto const_non_scalar_value = []() -> const std::string { return "CBA"; };
|
||||
EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value()));
|
||||
}
|
||||
|
||||
// Tests that ReturnRefOfCopy(v) works for reference types.
|
||||
TEST(ReturnRefOfCopyTest, WorksForReference) {
|
||||
int n = 42;
|
||||
|
Loading…
x
Reference in New Issue
Block a user