<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/138420>138420</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Unnecessary instantiation of templated function passed as a template parameter causes valid C++ code to fail compilation
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          TRDario
      </td>
    </tr>
</table>

<pre>
    The following code snippet compiles with MSVC and GCC, but fails to compile with Clang 20.1.0:

```
#include <unordered_map>
#include <vector>

template <class T>
concept standard_layout = std::is_standard_layout_v<T>;
template <class T, template <class...> class Z> struct is_specialization_of : std::false_type {};
template <class... Args, template <class...> class Z> struct is_specialization_of<Z<Args...>, Z> : std::true_type {};
template <class T, template <class...> class Z>
concept specialization_of = is_specialization_of<T, Z>::value;

template <class T> using fn = T (*)();

template <class T> T foo()
{
        static_assert(!specialization_of<T, std::pair>, "Compilation error!");
        return T{};
}

template <specialization_of<std::vector> T, fn<typename T::value_type> D> T bar()
{
        D();
        return T{};
}

template <specialization_of<std::unordered_map> T, fn<typename T::key_type> D1, fn<typename T::mapped_type> D2> T bar()
{
        D1();
        D2();
        return T{};
}

int main()
{
        bar<std::unordered_map<int, char>, foo, foo>();
}
```

It appears that in this example despite the std::vector overload of 'bar' not being chosen, 'foo<std::pair<int, char>>' is still instantiated and the error it emits causes the compilation to fail.

The error does not occur if 'foo' is a regular overloaded function, i.e replacing it with:
```
void foo(int) {}

void foo(char) {}

void foo(std::pair<int, char>) = delete;
```
does not result in any compilation errors.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysVk2P4zYP_jXKhVjDkfPlgw8ZZ-fFe-ilTXvYS6BIdKJWlgyJzjT99YXkfHgym90tWsCABZMin-chRVmEoA8WsWLzFzbfTERPR-er7c8b4bWb7J06V9sjQuOMcW_aHkA6hRCs7jokkK7ttMEAb5qO8NMvv9UgrIL_1TXjNex7gkZoE4Dc1XXwrI2wB-B5Ns1yVqxZnp5FfnnyNeOFttL0CoEVdW-dV-hR7VrRseLzB4cTSnL-YsnXhG1nBCWTNCIE2A426azEjiCQsEp4tTPi7HoCVmwgkIpQirUOuwf77sSKOoUoXp6E5zV8-JxlGSs-w-DyJS4D-V4SxAwdSi2M_kuQdnbnGmDF-o6hESbgjs4dAlu-sOXmSeYsy2DtD-Hf52dF_YUVdQw27Ish06Z3wMj3P4LrRxUZ1-QrimyeQd1e0Q2oTsL0OEB5Wn7oQ-zfxqa4W2B8xfia8TItyu_t3kLj3MU1X0fy0bsMJEjLnQgBPSXz9Cnem4id0P6iMOO8TicjOQN67zzjU8b5CFPpkXpvYTvWPC4-AP5a7lva2ykZqtNYVtSxlFa0GEnelEwFjn6bgfle-I_MN-91-48wPh71b0D9A893oNOnbq3oOlR3T_4tTtMHUhv-T1hqS9AKbT8Gjtmes6y1pYhfHsW1L1KzDa_4YYRhSDaelfn6_wSRpfAB6CgItAU66gD4p2g7g6AwdJoQ6Ijw0A7gTuiNEwriiePLpMsSrCPYYxr4RxfQDr26THjqh0Z-hB8BL0EHCKSNAW3jOCUtCFW6HiKK1OigCbDVFECKPmBIFjk6DuTSBZINLLe3fcphSBCdlL0H3VyxDXkFeDz0RtzJoYKmtzIGjUh1huCxM0JGhprSrXS5iEbKnpxWl2OfKJbXoZfgjKyJ-XPzd_SKG4sNKDRI1yk2QnEj6zH0JhVX2PM7nZIqIZuoqlBlUYoJVtPlbMHLZcnLybEqmwVfzRfLYtagXO0FnzarIl_u86naL8RMTHTFcz7P53kxXc3mvMzkKp81e9HIXC3Uar5ksxzbWApjTm3m_GGiQ-ixmharGc8nRuzRhPQXwbnFN0jWOMXmm4mv4qZP-_4Q2Cw3OlC4hyFNBqtfrUWJIQh_HvVLpOaa2zVyryF0ceAqELHWt9nSCS9aJPTXdjoJoxXUjL8w_jL8uVw6aqzepPemOhJ1IRaJvzL-etB07PeZdC3jrxHq5fWp8-53lMT4ayIYGH-9KHCq-N8BAAD__34248A">