googletest
googletest copied to clipboard
Test case compilation fails with Visual Studio 2022 and C++20
Describe the bug
When building the test case below with GoogleTest 1.12.1 and Visual Studio 2022 (17.2.4 or latest preview 17.3.0 preview 2.0) compilation fails in C++ 20 mode. When using an earlier standard than C++ 20 compilation succeeds.
Steps to reproduce the bug
#include "gmock/gmock.h"
class MockIBlockReader {
public:
MOCK_METHOD1(readBlock, void(void*));
};
TEST(a, b)
{
MockIBlockReader r;
EXPECT_CALL(r, readBlock(testing::_))
.WillOnce(
testing::WithArg<0>(
testing::Invoke([](auto dest){})
)
);
}
Compile with:
cl /I"D:\src\googletest\googletest\include" /I"D:\src\googletest\googlemock\include" /c testcase.cpp /EHsc /std:c++20
It errors out with:
...\include\gmock/gmock-actions.h(1432): error C2039: 'type': is not a member of 'std'
...\include\gtest/internal/gtest-internal.h(1323): note: see declaration of 'std'
testcase.cpp(16): note: see reference to class template instantiation 'testing::internal::WithArgsAction<a_b_Test::TestBody::<lambda_1>,0>' being compiled
...\include\gmock/gmock-actions.h(1457): error C2039: 'type': is not a member of 'std'
...\include\gtest/internal/gtest-internal.h(1323): note: see declaration of 'std'
Does the bug persist in the most recent commit?
Yes, the bug also happens at current HEAD: 4219e7254cb8c473f57f6065bd13d1520d7b708f
What operating system and version are you using?
Windows 10
What compiler and version are you using?
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.2.4
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
C:\Program Files\Microsoft Visual Studio\2022\Professional>cl /version
Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31329 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
The code in question was added with c144d78f8 by @jacobsa.
Thanks, Gregor
Thanks for the report, and the small test case. Unfortunately I can't reproduce this with the versions of MSVC I have access to.
The error messages are also pretty bad. :-( From the two lines mentioned, it seems like maybe the definition of std::tuple_element is wrong in your version of MSVC's standard library? Are you able to narrow it down at all?
If you want to play along: https://godbolt.org/z/oTKv4xGdv . I (ab)used the former fusing script for that.
I filed a bug with Microsoft: https://developercommunity.visualstudio.com/t/Cannot-compile-GoogleTest-based-test-in-/10087987
I just hit this too, and managed to minimize it further before I found @gjasny's bugs (here and MSVC). Seems to be regression due to the new SFINAE in c144d78f8295da3dbae3ad2d5fe66a9a42f8ce74, though it does feel more like a compiler bug than incorrect code in googlemock. It seems to actually be tied to /Zc:twophase, and the relevance of /std:c++20 is that this turns on /permissive- (and thus /Zc:twophase) by default. But the code doesn't actually have a problem with two-phase lookup - it compiles fine in g++ and clang.
https://godbolt.org/z/1Kzhzs41T is my smaller reproduction case, and https://godbolt.org/z/vn61oGox7 seems like one potential workaround (if this isn't enough data for MS to find/fix it). Basically, burying the use of std::tuple_element<…>::type in an alias template seems to help.
template <std::size_t I, typename T>
using tuple_element_t = typename std::tuple_element<I,T>::type;
- Action<R(typename std::tuple_element I, std::tuple<Args...>>::type...)>>::value,
+ Action<R(tuple_element_t<I, std::tuple<Args...>>...)>>::value,