Description
This minimal example triggers an internal compiler error (ICE) on Clang.
#include <tuple>
#include <functional>
template<class... Args>
struct StdTupleLike
{
template<class... Args2>
StdTupleLike(Args2...)
{}
};
template<class... Args>
StdTupleLike(Args...) -> StdTupleLike<Args...>;
template<class>
struct StdFunctionLike;
template<class Ret, class... Args>
struct StdFunctionLike<Ret(Args...)>
{
template<class U>
StdFunctionLike(U u): func{u}
{}
void operator()(Args... args)
{
func(args...);
}
Ret (*func)(Args...);
};
template<class... Funcs>
using FunctionsTuple = StdTupleLike<Funcs...>; // or: using FunctionsTuple = std::tuple<Funcs...>;
using NoFunctions = FunctionsTuple<>;
template<class Functions = NoFunctions>
inline auto execute(const Functions& = {}) -> void
{}
#if 1
struct TestSuite
{
inline explicit TestSuite(std::function<void(TestSuite &)> function) // ICE
{
function(*this);
}
};
#elif 0
struct TestSuite
{
inline explicit TestSuite(StdFunctionLike<void(TestSuite &)> function) // BUILD
{
function(*this);
}
};
#else
template<class T>
struct TestSuite
{
inline explicit TestSuite(T &&function) // BUILD
{
function(*this);
}
};
#endif
auto _ = TestSuite{[](auto &) {
auto _ = [] {
auto print = []() -> void {};
execute(FunctionsTuple{print});
};
}};
int main()
{
return 0;
}
Tested on:
clang version 21.0.0 (/opt/llvm-git/llvm-project fd8fb7148674456ce3fb338864c9aa9f576feb22)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /opt/llvm-git/bin
Replacing std::function<void(TestSuite &)>
with a custom wrapper like StdFunctionLike<void(TestSuite &)>
avoids the ICE.
Same goes for using a generic forwarding constructor template<class T> TestSuite(T&&)
.
This seems to be related to how auto lambdas and CTAD interact inside the TestSuite construction when std::function
is involved.
This compiles and runs correctly on GCC and MSVC.
The issue is isolated here on Compiler Explorer: https://godbolt.org/z/Ko5rYcros
Could you confirm if this is a known issue, or if a fix is planned?