[Bug]: Cannot mock recursive lambda with deducing this parameter
- Dominant language
- C++
- Stars
- 39.5k
- Forks
- 10.9k
- Avg merge
- 6d 13h
- Merged PRs (30d)
- 1
Description
### Describe the issue
Using `MockFunction` to mock a lambda function with deducing this self parameter gives a compile error with gcc 14.1 on Ubuntu 24.04
```
test.cpp: In member function ‘virtual void ::testing::Expr_test_1002_Test::TestBody()’:
test.cpp:975:20: error: ‘auto’ parameter not permitted in this context
975 | MockFunction mockNegVisit;
| ^~~~~~~~~~~~~~~~
test.cpp:975:20: error: a function type cannot have an explicit object parameter
test.cpp:975:20: note: the type of an explicit object member function is a regular function type
In file included from googletest/googlemock/include/gmock/gmock-function-mocker.h:43,
from googletest/googlemock/include/gmock/gmock.h:58,
from test.cpp:14:
googletest/googlemock/include/gmock/gmock-spec-builders.h: In instantiation of ‘class testing::MockFunction’:
test.cpp:975:44: required from here
test.cpp:975:20: note: 975 | MockFunction mockNegVisit;
test.cpp:975:20: note: | ^~~~~~~~~~~~
googletest/googlemock/include/gmock/gmock-spec-builders.h:2033:7: error: invalid use of incomplete type ‘struct testing::internal::SignatureOf’
2033 | class MockFunction : public internal::MockFunction> {
| ^~~~~~~~~~~~
googletest/googlemock/include/gmock/gmock-spec-builders.h:1955:8: note: declaration of ‘struct testing::internal::SignatureOf’
1955 | struct SignatureOf;
| ^~~~~~~~~~~
googletest/googlemock/include/gmock/gmock-spec-builders.h:2034:9: error: invalid use of incomplete type ‘struct testing::internal::SignatureOf’
2034 | using Base = internal::MockFunction>;
| ^~~~
googletest/googlemock/include/gmock/gmock-spec-builders.h:1955:8: note: declaration of ‘struct testing::internal::SignatureOf’
1955 | struct SignatureOf;
| ^~~~~~~~~~~
test.cpp: In lambda function:
test.cpp:983:20: error: ‘class testing::MockFunction’ has no member named ‘AsStdFunction’
983 | mockNegVisit.AsStdFunction(),
```
The code defines a recursive variant with visit lambda overloads
```
namespace {
struct Expr;
struct Neg {
shared_ptr expr;
};
struct Add {
shared_ptr lhs, rhs;
};
struct Mul {
shared_ptr lhs, rhs;
};
struct Expr: variant {
using variant::variant;
};
auto intVisit = [](int i) -> int { return i; };
auto negVisit = [](this const auto& self, const Neg& n) -> int { return -visit(self, *n.expr); };
auto addVisit = [](this const auto& self, const Add& a) -> int { return visit(self, *a.lhs) + visit(self, *a.rhs); };
auto mulVisit = [](this const auto& self, const Mul& m) -> int { return visit(self, *m.lhs) * visit(self, *m.rhs); };
template
struct overload: Ts... { using Ts::operator()...; };
auto evalExpr(const Expr& expr) -> int {
return visit(overload{
intVisit,
negVisit,
addVisit,
mulVisit,
},
expr);
}
}
```
test_1001 works
```
TEST(Expr, test_1001) {
// 5 + 2 = 7
EXPECT_EQ(evalExpr(Add{make_shared(5), make_shared(2)}), 7);
}
```
test_1002 fails to compile `mockNegVisit` though `mockIntVisit` without the auto self parameter works
```
TEST(Expr, test_1002) {
// 5 + 2 = 7
Add a{make_shared(5), make_shared(2)};
MockFunction mockIntVisit;
MockFunction mockNegVisit;
ON_CALL(mockIntVisit, Call).WillByDefault(ReturnArg<0>());
auto evalExprMock = [&mockIntVisit, &mockNegVisit](const Expr& expr) -> int {
return visit(overload{
mockIntVisit.AsStdFunction(),
mockNegVisit.AsStdFunction(),
addVisit,
mulVisit,
},
expr);
};
auto result = evalExprMock(a);
EXPECT_EQ(result, 7);
}
```
Is there a way to mock a recursive lambda?
### Steps to reproduce the problem
As above
### What version of GoogleTest are you using?
latest main branch of GoogleTest repo
### What operating system and version are you using?
Ubuntu 24.04
### What compiler and version are you using?
GCC 14.1
### What build system are you using?
CMake 3.29.3
### Additional context
_No response_
Contributor guide
Research direction
Start with the reproducer in the issue using GCC 14.1, then inspect MockFunction, SignatureOf, and AsStdFunction in googletest/googlemock/include/gmock/gmock-spec-builders.h. Compare the failing explicit-object-parameter signature with the working MockFunction case. Done means an agreed way for MockFunction to handle recursive lambdas, backed by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cmake, cpp
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100