<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/63556>63556</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang] Potential SFINAE regression with Clang-16
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
NuriAmari
</td>
</tr>
</table>
<pre>
Recently while upgrading from Clang-15, to Clang-16 I've come across of a piece of SFINAE that no longer works. I'm not sure if this is a bug, or should never have worked in the first place. Here is a Godbolt demonstrating the issue: https://godbolt.org/z/GbE53Wd3n. Apologies that the repro is somewhat complex, but I couldn't seem to reduce it further.
The crux of the issue is that `std::enable_if_t<!is_std_vector<typename LastArg<Args...>::type>, bool> = true>` where the last variadic type is some `std::vector<T>` used to trigger substitution failure, but no longer does. If we write the SFINAE guard `std::enable_if_t<is_std_vector<typename LastArg<Args...>::type>, bool> = false>` it works. Thanks!
Here is the same sample included in the Godbolt link:
```
#include <type_traits>
#include <vector>
#include <iostream>
#include <tuple>
#include <map>
// template to get last argument of variadic template
template<typename... Args>
struct LastArg {
using type =
typename std::tuple_element<sizeof...(Args) - 1, std::tuple<Args...>>::type;
};
template<>
struct LastArg<> {
using type = void;
};
// template to check if a type is any specialization of a templated class
template<template<class, class...> class, class>
struct is_instantiation_of : public std::false_type {};
template<template<class, class...> class T, class TInterface>
struct is_instantiation_of<T, T<TInterface>> : public std::true_type {};
// template to check if a type is any specialization of std::vector
template<typename T>
constexpr bool is_std_vector =
is_instantiation_of<std::vector, T>::value;
// two SFINAE guarded methods, one to be used if the last argument supplied is not a std::vector<T>
// the negation in the SFINAE doesn't work and both functions are considered for a call with std::vector<int>
template<typename... Args,
std::enable_if_t<!is_std_vector<typename LastArg<Args...>::type>, bool> =
true>
// comparing to false instead of negating with ! seems to work
// std::enable_if_t<is_std_vector<typename LastArg<Args...>::type>, bool> =
// false>
void Foo(Args&&... args) {
std::cout << "Foo";
}
template<typename... Args, typename U>
void Foo(Args&&... args, const std::vector<U>& allocator)
{
std::cout << "Bar";
}
int main() {
std::vector<int> int_vec;
Foo(const_cast<const std::vector<int>&>(int_vec));
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8V91u47wRfRr6ZrCGTMWyfeELrxN_DVAsijZFLw2aGklsKFLgj73Zpy-Gkuw4sRcB2n5GoEgiOXPOzPCMKLxXtUFcs_l3Nn-ciBga69Y_olObVjg1Odjybf13lGiCfoNTozRC7GonSmVqqJxtYauFqb_N5oxvIdjxsYBnxhdHBGlbBCGd9R5sBQI6hRLp9h-75x-bJwiNCGAsaGtqdHCy7tVP0-oWjA3go0NQFYRGeVAeBBxiTc6sA9_YqEsweEQHjThiWo4lKAOhQaiU8wE6LSRO4S9IhsjAH7Y8WB2gxNYaH5wIxIYWKO8jsnwDTQidZ_mG8R3ju7pfMLWuZnz3i_HdH4enef6vMjdT2HRW21qh76mQGYeds-TL2xZP9FbattP4k3AfYoBnkITcML4I4BFbCp3DMkoEFaCKLjTopsCyR5Zt-utLgyBd_EmxO2MlJ8ktKzIfSkKcb9CIg8a9qvaB5VvGZ8rvfSj3R5TBOpZvw1uHRrQIfxU-bFzN8u3G1X46nbL8qbdBU-iBAFurWf4ELH-E4GJ6XWRwaiighEQLH-AonBKlkkArR-5XsM7uXwYL0WNJxINTNeXex4MPKsSgrIFKKB0djhG7VEhpkQqkghPCyanQYxiqqY7Clb8Jxv8uEpXQfgyFCmPdvjTCvHrGZ-8z11_H-iO0nlx6QTUBykgdy0vRjtWplXklBL2JIhv--keeD8tgILEPTqjgCdCNGSPfm4PK-uBQtHeGQ-w03hlrRXcZGcZpw0DAttOCcmOhxtCXiHB1bNEEquBLuQwz--Xnp0tqptMpUE7OjnxwUYYxY8AW3_v3ANGnjUwFyPLH8S39znk-10WitUeNhIjlW69-oa0o8XyZ3PEVfIMZpf16zYcSuaqSAQlbPJ7v3zG6w6AfecfjmgYcrSpvmr4bcdmgfCXRFOfdKMwb-A6lElr9EmmHJTkel5UgtfD-cxYut_0Evu1n9vzh-uVHhsrvlfFBmKCSz72tgOS1iwet5CWwaTPte8aL73fC9yUo8HJ-DS_PJqCrhMQv4Eq6xLfwQjdXC9OG_4yZpPAm5P8-LR8l897WgJczMUmdDH92LokUXOnc9Wa4zf2jyz4SQ3EfhY54h9_JXmkvltBiaGyZ0mNNIn7AXutVdekXZzHwseu0olGfGr74RH_oGFduGwSDdR-xQTgHGNQf-sZKmgzClHCwoYEqGknTPQhH3yXGqxIdllBZBwKk0BpOKjQ33CtSiAEA_E6i-HaY9Cf04hHO0JHfR-fyo-8O4ZKc2L5lASUfRUl11kfQ1D1vxmfpW8TTXIrdHZv_79Z6xy39zk03TSFhhJ21Z8UuGC8oF2LQ73et4R1saWOAJLpbYJwnA_xKYN-V-e-zfekr__wqqm0qvXCjypIJXoDQ2kqRNuFqxPQFHt-F63nATSLKBGiFMowv74fmQ8WDMoESeg7OwCsx2EvhKe_36AybhhfpuhxN8RX9fY72-IEzKdd5ucpXYoLrWbFcLJd5tlxOmnUmssVyvnyo-KrKF_NZUchVKbJqkYlCzJfZRK15xvOs4ItZwR8eltOKL-UqO1SlXInFAy_ZQ4atUHqq9bGlj_lJ-oZeF_l8Xky0OKD26SjEucHTcBjgnE5Gbk1rvh1i7dlDppUP_mIlqKDTGUrS4YfNH-FvNiDpqx5FyWHt0HtSq7TXxmPSJDq9_nDYUKGJh6m0LeM78jH8-9Y5-2-UgfFdQuYZ3yXk_wkAAP__QOBHxQ">