Description
Found this while investigating #118560. This (started from libc++ std::visit
, now reduced beyond recognition)
struct S {
consteval void operator()() {}
};
template <class Fn>
constexpr void dispatch(Fn fn) {
fn();
}
template <class Visitor>
struct value_visitor {
constexpr void operator()() { visitor(); }
Visitor&& visitor;
};
template <class Visitor>
constexpr auto make_dispatch() {
return dispatch<value_visitor<S>>;
}
template <class Visitor>
constexpr void visit(Visitor&&) {
make_dispatch<Visitor>();
}
int main() { visit(S{}); }
results in a linker error:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.0/../../../../x86_64-linux-gnu/bin/ld: /tmp/example-02182a.o: in function `auto make_dispatch<S>()':
<source>:19:(.text._Z13make_dispatchI1SEDav[_Z13make_dispatchI1SEDav]+0x7): undefined reference to `void dispatch<value_visitor<S> >(value_visitor<S>)'
GCC accepts it without issue. Compiler Explorer link.
Issue seems related to immediate escalation, as making make_dispatch
or visit
consteval
solves the issue.