Skip to content

Dangling LLT reference in CodeGen/GlobalISel/MIPatternMatch.h #45

@Quuxplusone

Description

@Quuxplusone

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions