AssociatedIterator() = default;
AssociatedIterator(SectionChunk *head) : cur(head) {}
bool operator==(const AssociatedIterator &r) const { return cur == r.cur; }
- const SectionChunk &operator*() const { return *cur; }
+ // FIXME: Wrong const-ness, but it makes filter ranges work.
+ SectionChunk &operator*() const { return *cur; }
SectionChunk &operator*() { return *cur; }
AssociatedIterator &operator++() {
cur = cur->assocChildren;
// Returns true if two sections' associative children are equal.
bool ICF::assocEquals(const SectionChunk *a, const SectionChunk *b) {
- auto childClasses = [&](const SectionChunk *sc) {
- std::vector<uint32_t> classes;
- for (const SectionChunk &c : sc->children())
- if (!c.getSectionName().startswith(".debug") &&
- c.getSectionName() != ".gfids$y" && c.getSectionName() != ".gljmp$y")
- classes.push_back(c.eqClass[cnt % 2]);
- return classes;
+ // Ignore associated metadata sections that don't participate in ICF, such as
+ // debug info and CFGuard metadata.
+ auto considerForICF = [](const SectionChunk &assoc) {
+ StringRef Name = assoc.getSectionName();
+ return !(Name.startswith(".debug") || Name == ".gfids$y" ||
+ Name == ".gljmp$y");
};
- return childClasses(a) == childClasses(b);
+ auto ra = make_filter_range(a->children(), considerForICF);
+ auto rb = make_filter_range(b->children(), considerForICF);
+ return std::equal(ra.begin(), ra.end(), rb.begin(), rb.end(),
+ [&](const SectionChunk &ia, const SectionChunk &ib) {
+ return ia.eqClass[cnt % 2] == ib.eqClass[cnt % 2];
+ });
}
// Compare "non-moving" part of two sections, namely everything