https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119233

            Bug ID: 119233
           Summary: inside a template function the tracking of whether a
                    member function pointer of a class template escapes is
                    wrong
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rungecc at gmail dot com
  Target Milestone: ---

Reproducer (see online compiler: https://godbolt.org/z/bKh6vPjMv and
https://godbolt.org/z/rMs4dxje9)
```
// g++ -g -std=c++20 -O2
template <int ID>
struct foo {
    int get() { return 0; }
};

void register_f(void* data) {
    foo<0> f;
    auto mp = *static_cast<decltype(&foo<0>::get)*>(data);
    auto res = (f.*mp)();
}

template <auto Func>
void set() {
    auto&& f = Func;
    register_f(&f);
}

// whether helper is a generic function or a generic lambda does not matter.
// template <bool Flag = true>
// void helper() {
//     set<&foo<0>::get>();
// };


int main() {
    auto helper = [&]<bool Flag = true>() { set<&foo<0>::get>(); };
    helper();
    return 0;
}
```

Expected behavior: successfully complied and linked, just like `clang++` and
`msvc` do.

Actual behavior: ams gen succeeds, but `ld` complains:
```
in function `register_f(void*)':
<source>:11:(.text.startup+0xa): undefined reference to `foo<0>::get()'
collect2: error: ld returned 1 exit status
```

Workaround: if explicitly instantiate `class foo<0>`, the issue is gone, see
online compiler (https://godbolt.org/z/o3fKrrGr1).

Version:

g++
(Compiler-Explorer-Build-gcc-c6b277f1dc6d11ad6d398967b8d645e7c3c6ad71-binutils-2.42)
15.0.1 20250311 (experimental)

Reply via email to