Provide basic type safety for array_pod_sort comparators.

This makes using array_pod_sort significantly safer. The implementation relies
on function pointer casting but that should be safe as we're dealing with void*
here.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2013-09-22 14:09:50 +00:00
parent 7f80b75b96
commit 0d293e45b6
11 changed files with 38 additions and 42 deletions

View File

@@ -293,12 +293,16 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
get_array_pod_sort_comparator(*Start)); get_array_pod_sort_comparator(*Start));
} }
template<class IteratorTy> template <class IteratorTy>
inline void array_pod_sort(IteratorTy Start, IteratorTy End, inline void array_pod_sort(
int (*Compare)(const void*, const void*)) { IteratorTy Start, IteratorTy End,
int (*Compare)(
const typename std::iterator_traits<IteratorTy>::value_type *,
const typename std::iterator_traits<IteratorTy>::value_type *)) {
// Don't dereference start iterator of empty sequence. // Don't dereference start iterator of empty sequence.
if (Start == End) return; if (Start == End) return;
qsort(&*Start, End-Start, sizeof(*Start), Compare); qsort(&*Start, End - Start, sizeof(*Start),
reinterpret_cast<int (*)(const void *, const void *)>(Compare));
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@@ -86,10 +86,9 @@ public:
private: private:
// ValLessThan - Provide a sorting comparator for Values elements... // ValLessThan - Provide a sorting comparator for Values elements...
static int ValLessThan(const void *VT1, const void *VT2) { static int ValLessThan(const PassNameParser::OptionInfo *VT1,
typedef PassNameParser::OptionInfo ValType; const PassNameParser::OptionInfo *VT2) {
return std::strcmp(static_cast<const ValType *>(VT1)->Name, return std::strcmp(VT1->Name, VT2->Name);
static_cast<const ValType *>(VT2)->Name);
} }
}; };

View File

@@ -2040,9 +2040,8 @@ struct MBBPriorityInfo {
// block (the unsigned), and then on the MBB number. // block (the unsigned), and then on the MBB number.
// //
// EnableGlobalCopies assumes that the primary sort key is loop depth. // EnableGlobalCopies assumes that the primary sort key is loop depth.
static int compareMBBPriority(const void *L, const void *R) { static int compareMBBPriority(const MBBPriorityInfo *LHS,
const MBBPriorityInfo *LHS = static_cast<const MBBPriorityInfo*>(L); const MBBPriorityInfo *RHS) {
const MBBPriorityInfo *RHS = static_cast<const MBBPriorityInfo*>(R);
// Deeper loops first // Deeper loops first
if (LHS->Depth != RHS->Depth) if (LHS->Depth != RHS->Depth)
return LHS->Depth > RHS->Depth ? -1 : 1; return LHS->Depth > RHS->Depth ? -1 : 1;

View File

@@ -1104,11 +1104,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
} }
} }
static int compareBySuffix(const void *a, const void *b) { static int compareBySuffix(const MCSectionELF *const *a,
const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); const MCSectionELF *const *b) {
const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); const StringRef &NameA = (*a)->getSectionName();
const StringRef &NameA = secA->getSectionName(); const StringRef &NameB = (*b)->getSectionName();
const StringRef &NameB = secB->getSectionName();
const unsigned sizeA = NameA.size(); const unsigned sizeA = NameA.size();
const unsigned sizeB = NameB.size(); const unsigned sizeB = NameB.size();
const unsigned len = std::min(sizeA, sizeB); const unsigned len = std::min(sizeA, sizeB);

View File

@@ -42,9 +42,9 @@ const MCSymbol *MCELFObjectTargetWriter::undefinedExplicitRelSym(const MCValue &
// ELF doesn't require relocations to be in any order. We sort by the r_offset, // ELF doesn't require relocations to be in any order. We sort by the r_offset,
// just to match gnu as for easier comparison. The use type and index is an // just to match gnu as for easier comparison. The use type and index is an
// arbitrary way of making the sort deterministic. // arbitrary way of making the sort deterministic.
static int cmpRel(const void *AP, const void *BP) { static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
const ELFRelocationEntry &A = *(const ELFRelocationEntry *)AP; const ELFRelocationEntry &A = *AP;
const ELFRelocationEntry &B = *(const ELFRelocationEntry *)BP; const ELFRelocationEntry &B = *BP;
if (A.r_offset != B.r_offset) if (A.r_offset != B.r_offset)
return B.r_offset - A.r_offset; return B.r_offset - A.r_offset;
if (B.Type != A.Type) if (B.Type != A.Type)

View File

@@ -4059,9 +4059,8 @@ bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
// We are comparing pointers, but the pointers are relative to a single string. // We are comparing pointers, but the pointers are relative to a single string.
// Thus, this should always be deterministic. // Thus, this should always be deterministic.
static int rewritesSort(const void *A, const void *B) { static int rewritesSort(const AsmRewrite *AsmRewriteA,
const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A); const AsmRewrite *AsmRewriteB) {
const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B);
if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
return -1; return -1;
if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())

View File

@@ -135,9 +135,9 @@ const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) {
return TheTarget; return TheTarget;
} }
static int TargetArraySortFn(const void *LHS, const void *RHS) { static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS,
typedef std::pair<StringRef, const Target*> pair_ty; const std::pair<StringRef, const Target *> *RHS) {
return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first); return LHS->first.compare(RHS->first);
} }
void TargetRegistry::printRegisteredTargetsForVersion() { void TargetRegistry::printRegisteredTargetsForVersion() {

View File

@@ -3042,14 +3042,8 @@ bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) {
return true; return true;
} }
static int compareNames(const void *A, const void *B) { static int compareNames(Constant *const *A, Constant *const *B) {
const GlobalValue *VA = *reinterpret_cast<GlobalValue* const*>(A); return (*A)->getName().compare((*B)->getName());
const GlobalValue *VB = *reinterpret_cast<GlobalValue* const*>(B);
if (VA->getName() < VB->getName())
return -1;
if (VB->getName() < VA->getName())
return 1;
return 0;
} }
static void setUsedInitializer(GlobalVariable &V, static void setUsedInitializer(GlobalVariable &V,

View File

@@ -699,9 +699,10 @@ namespace {
}; };
} }
static int ConstantIntSortPredicate(const void *P1, const void *P2) { static int ConstantIntSortPredicate(ConstantInt *const *P1,
const ConstantInt *LHS = *(const ConstantInt*const*)P1; ConstantInt *const *P2) {
const ConstantInt *RHS = *(const ConstantInt*const*)P2; const ConstantInt *LHS = *P1;
const ConstantInt *RHS = *P2;
if (LHS->getValue().ult(RHS->getValue())) if (LHS->getValue().ult(RHS->getValue()))
return 1; return 1;
if (LHS->getValue() == RHS->getValue()) if (LHS->getValue() == RHS->getValue())

View File

@@ -813,9 +813,10 @@ static bool testSubClass(const CodeGenRegisterClass *A,
/// Register classes with the same registers, spill size, and alignment form a /// Register classes with the same registers, spill size, and alignment form a
/// clique. They will be ordered alphabetically. /// clique. They will be ordered alphabetically.
/// ///
static int TopoOrderRC(const void *PA, const void *PB) { static int TopoOrderRC(CodeGenRegisterClass *const *PA,
const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA; CodeGenRegisterClass *const *PB) {
const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB; const CodeGenRegisterClass *A = *PA;
const CodeGenRegisterClass *B = *PB;
if (A == B) if (A == B)
return 0; return 0;

View File

@@ -41,9 +41,9 @@ static int StrCmpOptionName(const char *A, const char *B) {
return (a < b) ? -1 : 1; return (a < b) ? -1 : 1;
} }
static int CompareOptionRecords(const void *Av, const void *Bv) { static int CompareOptionRecords(Record *const *Av, Record *const *Bv) {
const Record *A = *(const Record*const*) Av; const Record *A = *Av;
const Record *B = *(const Record*const*) Bv; const Record *B = *Bv;
// Sentinel options precede all others and are only ordered by precedence. // Sentinel options precede all others and are only ordered by precedence.
bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");