Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Failure to recognise function type for static member function template in class template #91362

Closed
cuavas opened this issue May 7, 2024 · 5 comments
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party

Comments

@cuavas
Copy link

cuavas commented May 7, 2024

We noticed this as code using sol2 failing to compile with clang 18. It was reported to that project here: ThePhD/sol2#1581 (also as duplicate ThePhD/sol2#1588).

It’s demonstrated by this reduced test case:

#include <type_traits>

template <typename T>
struct class_tmpl {
    template <bool B> static int call_e() { return 0; }
    template <bool B> static int call_ne() noexcept { return 0; }
    template <bool B> static int call() noexcept(std::is_nothrow_copy_assignable<T>::value) { return 0; }
};

int main(int argc, char *argv[])
{
    using function_ptr = int (*)();
    function_ptr f1 = &class_tmpl<int>::call_e<false>;
    function_ptr f2 = &class_tmpl<int>::call_ne<false>;
    function_ptr f3 = &class_tmpl<int>::call<false>;
    return 0;
}

With clang 18 (including clang 18.1), compilation fails with -std=c++14 or -std=c++17 with the following error:

test.cpp:15:24: error: address of overloaded function 'call' does not match required type 'int ()'
   15 |     function_ptr f3 = &class_tmpl<int>::call<false>;
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:7:34: note: candidate template ignored: substitution failure [with B = false]
    7 |     template <bool B> static int call() noexcept(std::is_nothrow_copy_assignable<T>::value) { return 0; }
      |                                  ^
1 error generated.

When the noexcept specification uses an expression that depends on the class template arguments, clang reports a substitution failure. The code compiles with clang 17 and earlier, as far back as clang 6 at least.

@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" and removed new issue labels May 7, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented May 7, 2024

@llvm/issue-subscribers-clang-frontend

Author: Vas Crabb (cuavas)

We noticed this as code using sol2 failing to compile with clang 18. It was reported to that project here: ThePhD/sol2#1581 (also as duplicate ThePhD/sol2#1588).

It’s demonstrated by this reduced test case:

#include &lt;type_traits&gt;

template &lt;typename T&gt;
struct class_tmpl {
    template &lt;bool B&gt; static int call_e() { return 0; }
    template &lt;bool B&gt; static int call_ne() noexcept { return 0; }
    template &lt;bool B&gt; static int call() noexcept(std::is_nothrow_copy_assignable&lt;T&gt;::value) { return 0; }
};

int main(int argc, char *argv[])
{
    using function_ptr = int (*)();
    function_ptr f1 = &amp;class_tmpl&lt;int&gt;::call_e&lt;false&gt;;
    function_ptr f2 = &amp;class_tmpl&lt;int&gt;::call_ne&lt;false&gt;;
    function_ptr f3 = &amp;class_tmpl&lt;int&gt;::call&lt;false&gt;;
    return 0;
}

With clang 18 (including clang 18.1), compilation fails with -std=c++14 or -std=c++17 with the following error:

test.cpp:15:24: error: address of overloaded function 'call' does not match required type 'int ()'
   15 |     function_ptr f3 = &amp;class_tmpl&lt;int&gt;::call&lt;false&gt;;
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:7:34: note: candidate template ignored: substitution failure [with B = false]
    7 |     template &lt;bool B&gt; static int call() noexcept(std::is_nothrow_copy_assignable&lt;T&gt;::value) { return 0; }
      |                                  ^
1 error generated.

When the noexcept specification uses an expression that depends on the class template arguments, clang reports a substitution failure. The code compiles with clang 17 and earlier, as far back as clang 6 at least.

cuavas added a commit to mamedev/mame that referenced this issue May 7, 2024
When taking a pointer to a static member function template in a class
template, clang reports a substitution error if the noexcept
specification uses an expression that depends on class template
arguments.

See llvm/llvm-project#91362 on GitHub.
@cuavas
Copy link
Author

cuavas commented May 7, 2024

Even simpler test case (without using the <type_traits> header) that fails as C++17:

template <typename T>
struct class_tmpl {
    template <bool B> static void call_e() { }
    template <bool B> static void call_ne() noexcept { }
    template <bool B> static void call() noexcept(sizeof(T) > 1) { }
};

int main(int argc, char *argv[])
{
    using function_ptr = void (*)();
    function_ptr f1 = &class_tmpl<int>::call_e<false>;
    function_ptr f2 = &class_tmpl<int>::call_ne<false>;
    function_ptr f3 = &class_tmpl<int>::call<false>;
    return 0;
}

Error with clang 18.1.4:

% clang++ -std=c++17 test.cpp
test.cpp:13:24: error: address of overloaded function 'call' does not match required type 'void ()'
   13 |     function_ptr f3 = &class_tmpl<int>::call<false>;
      |                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:5:35: note: candidate template ignored: substitution failure [with B = false]
    5 |     template <bool B> static void call() noexcept(sizeof(T) > 1) { }
      |                                   ^
1 error generated.

@zyn0217
Copy link
Contributor

zyn0217 commented May 8, 2024

This should have been resolved by #90760.
(I'll close the issue once that gets applied to godbolt. ATM we encounter a crash with an assertion build for the case above: https://gcc.godbolt.org/z/vcEr5sroY)

@zyn0217 zyn0217 added the confirmed Verified by a second party label May 8, 2024
@cuavas
Copy link
Author

cuavas commented May 8, 2024

It seems godbolt has updated to a build that successfully compiles the code.

@zyn0217
Copy link
Contributor

zyn0217 commented May 9, 2024

Yeah, so let's close the issue and feel free to re-open it if you find other cases.

@zyn0217 zyn0217 closed this as completed May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party
Projects
None yet
Development

No branches or pull requests

4 participants