-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Compiling Clang in -std=c++23
mode gives (among many other warnings/errors) this hard error:
llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h:371:45: error: no viable conversion from returned value of type 'LLT' to function return type 'bind_ty<LLT>'
371 | inline bind_ty<LLT> m_Type(LLT Ty) { return Ty; }
| ^~
This was legal C++20, but became ill-formed in C++23 because of my P2266 "Simpler implicit move." The problem here is that we're trying to return the parameter variable Ty
by implicit move (so Ty
is an rvalue), but the constructor bind_ty(LLT&)
requires a mutable lvalue reference, not an rvalue. The reason bind_ty
wants an lvalue is because it's going to capture a reference to it. So here P2266 has caught a bug: in C++20-and-earlier this line returned a bind_ty
capturing a reference to Ty
(which is now out-of-scope and so the reference is dangling). In C++23-and-later this line is, thankfully, ill-formed.
This bug was introduced in 2020 by @arsenm's commit de25647, which (blindly?) search-and-replaced LLT&
into LLT
everywhere in the codebase. Where there's one bug, there's often two: I think that specific commit should be looked at more closely, to see if any more of those reference-qualifiers were load-bearing.
To preserve the current undefined behavior, it suffices to write:
inline bind_ty<LLT> m_Type(LLT Ty) { return bind_ty<LLT>(Ty); }
I think a more appropriate fix would be:
inline bind_ty<LLT> m_Type(LLT& Ty) { return Ty; }
However, at first glance it seems that m_Type
is an unused function, and in fact has been unused ever since it was introduced in 2036f44. If so, then this line could just be removed entirely.