This is an archive of the discontinued LLVM Phabricator instance.

[LLParser] Handle mixed blockaddress forward references with names and IDs
AcceptedPublic

Authored by MichielDerhaeg on Nov 1 2022, 7:13 AM.

Details

Reviewers
dexonsmith
Summary

ValIDs of the LocalID and LocalName kind were mixed in the same std::map.
std::less is not defined in that case. Operations on the std::map were
undefined and the incorrect basic block is parsed.

Diff Detail

Event Timeline

MichielDerhaeg created this revision.Nov 1 2022, 7:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2022, 7:13 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
MichielDerhaeg requested review of this revision.Nov 1 2022, 7:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 1 2022, 7:13 AM

This was a bug reported a while ago on the old bugzilla: https://bugs.llvm.org/show_bug.cgi?id=46183

Would it be simpler to define < for that case? Or, we could define a custom one to send to the std::map:

struct CompareValID {
  static bool operator<(const ValID &LHS, const ValID &RHS) {
    if (LHS.Kind != RHS.Kind)
      return LHS.Kind < RHS.Kind;
    return LHS < RHS;
  }
};

Would it be simpler to define < for that case? Or, we could define a custom one to send to the std::map:

struct CompareValID {
  static bool operator<(const ValID &LHS, const ValID &RHS) {
    if (LHS.Kind != RHS.Kind)
      return LHS.Kind < RHS.Kind;
    return LHS < RHS;
  }
};

That was my initial idea, but if you search for other ForwardRef-related datastructures in LLParser.cpp, you'll see that they solved it this way for all other cases as well.
I did it like this to remain consistent.

dexonsmith accepted this revision.Nov 9 2022, 1:37 PM
dexonsmith added a subscriber: dblaikie.

Would it be simpler to define < for that case? Or, we could define a custom one to send to the std::map:

struct CompareValID {
  static bool operator<(const ValID &LHS, const ValID &RHS) {
    if (LHS.Kind != RHS.Kind)
      return LHS.Kind < RHS.Kind;
    return LHS < RHS;
  }
};

That was my initial idea, but if you search for other ForwardRef-related datastructures in LLParser.cpp, you'll see that they solved it this way for all other cases as well.
I did it like this to remain consistent.

Hmm. Okay, the pattern followed elsewhere is reasonable. LGTM then.

That said, the pattern of splitting the map seems to add boilerplate and I'm not convinced it's less error-prone than a shared map. @dblaikie, any thoughts? (I.e., would it be better to tidy it up, or is there some value in using the split maps?)

This revision is now accepted and ready to land.Nov 9 2022, 1:37 PM

Would it be simpler to define < for that case? Or, we could define a custom one to send to the std::map:

struct CompareValID {
  static bool operator<(const ValID &LHS, const ValID &RHS) {
    if (LHS.Kind != RHS.Kind)
      return LHS.Kind < RHS.Kind;
    return LHS < RHS;
  }
};

That was my initial idea, but if you search for other ForwardRef-related datastructures in LLParser.cpp, you'll see that they solved it this way for all other cases as well.
I did it like this to remain consistent.

Hmm. Okay, the pattern followed elsewhere is reasonable. LGTM then.

That said, the pattern of splitting the map seems to add boilerplate and I'm not convinced it's less error-prone than a shared map. @dblaikie, any thoughts? (I.e., would it be better to tidy it up, or is there some value in using the split maps?)

Yeah, at least at a glance, and with your framing here - I tend to agree that all this duplication seems unfortunate & I guess, by the sounds of it, there's more of this duplication pre-existing in other instances that could be cleaned up if we generalized the op<?