Skip to content

[CodeGen] std::less<llvm::rdf::RegisterRef> and std::equal_to<llvm::rdf::RegisterRef> full specializations don't satisfy the standard requirements #160684

@frederick-vs-ja

Description

@frederick-vs-ja

The following full specializations don't satisfy [namespace.std]/5.2.

  1. A program may explicitly instantiate a class template defined in the standard library only if the declaration
  • (5.1) depends on the name of at least one program-defined type, and
  • (5.2) the instantiation meets the standard library requirements for the original template.

template <> struct equal_to<llvm::rdf::RegisterRef> {
constexpr equal_to(const llvm::rdf::PhysicalRegisterInfo &pri) : PRI(&pri) {}
bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const {
return PRI->equal_to(A, B);
}
private:
// Make it a pointer just in case. See comment in `less` below.
const llvm::rdf::PhysicalRegisterInfo *PRI;
};

template <> struct less<llvm::rdf::RegisterRef> {
constexpr less(const llvm::rdf::PhysicalRegisterInfo &pri) : PRI(&pri) {}
bool operator()(llvm::rdf::RegisterRef A, llvm::rdf::RegisterRef B) const {
return PRI->less(A, B);
}
private:
// Make it a pointer because apparently some versions of MSVC use std::swap
// on the std::less specialization.
const llvm::rdf::PhysicalRegisterInfo *PRI;
};

These full specializations violate the requirements by being non-default-constructible, and arguably, being non-empty/stateful.

Perhaps it's better to specify non-std comparators rather than simply use std::set<RegisterRef> or std::map<RegisterRef, T>.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions