-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Closed
Labels
c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"regressionrejects-valid
Description
This was found internally at Intel from some customer code. The original test case was stripped down to:
template <bool> using enable_if_t = int;
template <class Ty> Ty Returns_exactly() noexcept;
struct InvokeBase {
template <class Fx, class... Args>
static auto Call(Fx func, Args... args) -> decltype(func(args...));
};
template <class Fx1, class Fx2 = Fx1, bool = false> struct Invoke;
template <class Fx1, class Fx2> struct Invoke<Fx1, Fx2, false> : InvokeBase {};
template <int> struct F { };
template <class...> struct InvocableR;
template <class Rx, class Callable, class... Args>
struct InvocableR<Rx, Callable, Args...> :
F<noexcept(Invoke<Rx>::Call(Returns_exactly<Rx>(), Returns_exactly<Callable>()))> {
static constexpr bool value = false;
};
template <class Rx, class... Args> constexpr bool IsInvocableRV = InvocableR<Rx, Args...>::value;
template <class, class... Types> class FuncClass {
public:
template <class Fx> using EnableIfCallable = enable_if_t<IsInvocableRV<Fx, Types...>>;
};
template <class> struct FuncImpl;
template <class Ret, class... Types> struct FuncImpl<Ret(Types...)> {
using type = FuncClass<Ret, Types...>;
};
template <class FTy> class function {
using Base = typename FuncImpl<FTy>::type;
public:
template <class Fx, typename Base::template EnableIfCallable<Fx> = 0> function(Fx) {}
};
struct codeloc {
static constexpr codeloc current_location(const char *name = __builtin_FUNCTION()) {
return codeloc();
}
constexpr codeloc() {}
};
class buff {
public:
buff(buff &, codeloc = codeloc::current_location());
};
void Help(function<void(buff)>) {
}
void Test() {
Help([](buff) {});
}https://godbolt.org/z/qao5jhv1e
And with help from @Endilll it was further reduced to:
struct buff {
buff(buff &, const char * = __builtin_FUNCTION());
};
template <class Ty>
Ty declval();
template <class Fx>
auto Call(buff arg) -> decltype(Fx{}(arg));
template <typename>
struct F {};
template <class Fx>
struct InvocableR : F<decltype(Call<Fx>(declval<buff>()))> {
static constexpr bool value = false;
};
template <class Fx, bool = InvocableR<Fx>::value>
void Help(Fx) {}
void Test() {
Help([](buff) {});
}https://godbolt.org/z/3n3K46WT8
It's possibly worth noting that the behavior may be different on Windows than on Linux.
CC @cor3ntin
Metadata
Metadata
Assignees
Labels
c++20clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"regressionrejects-valid
Type
Projects
Status
Done