<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/81155>81155</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Potential 18.x regression from 8c2b0d4175dcfe669a43d0173fd00ed3
</td>
</tr>
<tr>
<th>Labels</th>
<td>
c++20,
clang:frontend,
regression,
rejects-valid
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
AaronBallman
</td>
</tr>
</table>
<pre>
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
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV0tv67YS_jX0ZhBDJv2QF144coQb3Itzi8DtWQYURVk8pUmVpBy7v74g9bD8iJuzKAoYiCQOZ7755uNwQq0VO8X5Cs2e0WwzorUrtVmtqdHqmUq5p2qU6fy02pbCwge1UOha5SCU40ZRKU9AHbwqxyUURu_B6j0HVlun99wA0zkfw7bkoI3YCUUlOG4dMGp58GadEVXFc8j1hwKnEVmjaIOiNZpH7S-8Or6vJHUcEEkyrSUiL1BboXbAFc0kfxfFuwNENh4ZIs-3u5ik1sL25HduT_DGXW2UfedHypw8IRwjvASl-ZHx6uzBOlMzn-BB_86fPWq0aJcAbt2nR4QTCM_j8RjWZmcReensraNOMKC105BQKRGO0yMUtWJ-lzf2m6jfhJfw5JHmnEl3qjjCcWMX08YM4aX_dTjRYvMg6_Q46XFBesSBqPajZzO8F1Ra7mNe5PwTXu_sTVobv4qTcwhE1tecfpJAKGfvN_Wm8DBZz80lEOYF8vYgkbdz1UJdvP3ndbzjOWk8DPe21eySbSWQIpL0GsNxT9Pb0bsna0TWrTCu9dnZBJ36ALcGffizWaORl6FoWxEyrazjx8o0AjhQWfOhDL6kq7e7cr_2_WrPXP0WYtzh7sxXQ0MA9Hnoi7jbU8WbwI0Ua8WS8NSnXdWZFKxvLp8c3b6nvISe8lp0jAbQg0aDSHKRVBC6hxSQdGm8fI3FobxrxV73lXxEOXf3c79xkQTTuId0o4QmV99dmn7Q0dZtvUrna52mabDNi-9YTmg1CNrEbA492YTgiu75EHbjolFBaH195J8oJU7Ovn201l1nel3gpoDhrG4g8g8d9tCjfTtue9QNBxdNwd93UrOH562zYbUxXLl3qRltIwUjYCU1gPA6gPeA3t-zWkgn1Hv667dk-_r_b_35HkYCMKEndBFaI9Ib9PjhFk57AX6WZUNsVhfFg0PllxGOGys8DzrtCCGbPlIoxZ3sH1xpBy1y-A-XVXsPhh0k8Z_bgI28LxjpEwm7t9y6QZIt5NZnM_2cXXU8XMG5N5mUzlXW54RThNOdzjMt3VibHcLpnwinf1A9-1EeJnwol7XK4UO4Ekouq2ZwQtPoReVCSgnCNZNWbVzJDRie14znD6ajVn2X5fmkHkOF_Z267tbi4WjVLG5PYXA5UHmlwc9HiX7vcDoKyKmn8nYcSo9djeLG4nGcrhtcX-Pp9fDxBYg3E0C44v3dPsAXUmjbCsJxxwdJQlX-oSv6AfjhqHdx_6bH60v35fbQ3emB__7RIor8dzr_vo2HiF4dwgsLlbZWZPIEH9q4EpR24bIrqQNXcsh4SQ9CG9jTE2QcclEU3Dck0Aq-C5XrD-utlX__n1D1cTwMkiT-vDJtiHJCwShfkXxJlnTEV5NFtJhGMVlGo3JFJrhgs2xC54ucLhZkOssWC7qczOIFZphOR2KFIzyNcBRP5tGcRGPOY17MJvPlYjItMkLRNOJ7KuRYysPe5z4S1tZ8FU8ms9lI0oxLG_55w5gh_IzwM44Q9tO2_yKp2iGyLoxWjqu8XzB8Z7i1oe_2n35w5uzTgUoRDGebkVn5qE9ZvbNoGklhnT3jcMJJvvpFO66coBIm8fgIZ8dNV4sZzqJ8OlnMclbw-XxJpySPJgtS5FHEczKqjVxd1Vm4ss7GTO8RTn209s9TZbSHiHAaKLAIp4GFvwIAAP__sS9m9g">