From 1308256cf8ca723f9304481e2013888b177d6f50 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 22 Sep 2013 14:09:50 +0000 Subject: [PATCH] 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. llvm-svn: 191175 --- include/llvm/ADT/STLExtras.h | 12 ++++++++---- include/llvm/Support/PassNameParser.h | 7 +++---- lib/CodeGen/RegisterCoalescer.cpp | 5 ++--- lib/MC/ELFObjectWriter.cpp | 9 ++++----- lib/MC/MCELFObjectTargetWriter.cpp | 6 +++--- lib/MC/MCParser/AsmParser.cpp | 5 ++--- lib/Support/TargetRegistry.cpp | 6 +++--- lib/Transforms/IPO/GlobalOpt.cpp | 10 ++-------- lib/Transforms/Utils/SimplifyCFG.cpp | 7 ++++--- utils/TableGen/CodeGenRegisters.cpp | 7 ++++--- utils/TableGen/OptParserEmitter.cpp | 6 +++--- 11 files changed, 38 insertions(+), 42 deletions(-) diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index bfe1392a679..3aa81833532 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -293,12 +293,16 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) { get_array_pod_sort_comparator(*Start)); } -template -inline void array_pod_sort(IteratorTy Start, IteratorTy End, - int (*Compare)(const void*, const void*)) { +template +inline void array_pod_sort( + IteratorTy Start, IteratorTy End, + int (*Compare)( + const typename std::iterator_traits::value_type *, + const typename std::iterator_traits::value_type *)) { // Don't dereference start iterator of empty sequence. if (Start == End) return; - qsort(&*Start, End-Start, sizeof(*Start), Compare); + qsort(&*Start, End - Start, sizeof(*Start), + reinterpret_cast(Compare)); } //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h index a73dc8ff289..c0914b1f2f0 100644 --- a/include/llvm/Support/PassNameParser.h +++ b/include/llvm/Support/PassNameParser.h @@ -86,10 +86,9 @@ public: private: // ValLessThan - Provide a sorting comparator for Values elements... - static int ValLessThan(const void *VT1, const void *VT2) { - typedef PassNameParser::OptionInfo ValType; - return std::strcmp(static_cast(VT1)->Name, - static_cast(VT2)->Name); + static int ValLessThan(const PassNameParser::OptionInfo *VT1, + const PassNameParser::OptionInfo *VT2) { + return std::strcmp(VT1->Name, VT2->Name); } }; diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index d429b37334a..c776dd31225 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -2040,9 +2040,8 @@ struct MBBPriorityInfo { // block (the unsigned), and then on the MBB number. // // EnableGlobalCopies assumes that the primary sort key is loop depth. -static int compareMBBPriority(const void *L, const void *R) { - const MBBPriorityInfo *LHS = static_cast(L); - const MBBPriorityInfo *RHS = static_cast(R); +static int compareMBBPriority(const MBBPriorityInfo *LHS, + const MBBPriorityInfo *RHS) { // Deeper loops first if (LHS->Depth != RHS->Depth) return LHS->Depth > RHS->Depth ? -1 : 1; diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 2db59acd504..402a6167f5a 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -1104,11 +1104,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, } } -static int compareBySuffix(const void *a, const void *b) { - const MCSectionELF *secA = *static_cast(a); - const MCSectionELF *secB = *static_cast(b); - const StringRef &NameA = secA->getSectionName(); - const StringRef &NameB = secB->getSectionName(); +static int compareBySuffix(const MCSectionELF *const *a, + const MCSectionELF *const *b) { + const StringRef &NameA = (*a)->getSectionName(); + const StringRef &NameB = (*b)->getSectionName(); const unsigned sizeA = NameA.size(); const unsigned sizeB = NameB.size(); const unsigned len = std::min(sizeA, sizeB); diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp index ec7397d748f..0c39e4a17ef 100644 --- a/lib/MC/MCELFObjectTargetWriter.cpp +++ b/lib/MC/MCELFObjectTargetWriter.cpp @@ -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, // just to match gnu as for easier comparison. The use type and index is an // arbitrary way of making the sort deterministic. -static int cmpRel(const void *AP, const void *BP) { - const ELFRelocationEntry &A = *(const ELFRelocationEntry *)AP; - const ELFRelocationEntry &B = *(const ELFRelocationEntry *)BP; +static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) { + const ELFRelocationEntry &A = *AP; + const ELFRelocationEntry &B = *BP; if (A.r_offset != B.r_offset) return B.r_offset - A.r_offset; if (B.Type != A.Type) diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index dcf54b0b942..c1f825ae785 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -4059,9 +4059,8 @@ bool AsmParser::parseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) { // We are comparing pointers, but the pointers are relative to a single string. // Thus, this should always be deterministic. -static int rewritesSort(const void *A, const void *B) { - const AsmRewrite *AsmRewriteA = static_cast(A); - const AsmRewrite *AsmRewriteB = static_cast(B); +static int rewritesSort(const AsmRewrite *AsmRewriteA, + const AsmRewrite *AsmRewriteB) { if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer()) return -1; if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer()) diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index 9c81327615c..0c90c17fefb 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -135,9 +135,9 @@ const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) { return TheTarget; } -static int TargetArraySortFn(const void *LHS, const void *RHS) { - typedef std::pair pair_ty; - return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first); +static int TargetArraySortFn(const std::pair *LHS, + const std::pair *RHS) { + return LHS->first.compare(RHS->first); } void TargetRegistry::printRegisteredTargetsForVersion() { diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 7ba7f86cb40..cf15580b039 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -3042,14 +3042,8 @@ bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) { return true; } -static int compareNames(const void *A, const void *B) { - const GlobalValue *VA = *reinterpret_cast(A); - const GlobalValue *VB = *reinterpret_cast(B); - if (VA->getName() < VB->getName()) - return -1; - if (VB->getName() < VA->getName()) - return 1; - return 0; +static int compareNames(Constant *const *A, Constant *const *B) { + return (*A)->getName().compare((*B)->getName()); } static void setUsedInitializer(GlobalVariable &V, diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 0dea844aeb9..0e56904ebde 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -699,9 +699,10 @@ namespace { }; } -static int ConstantIntSortPredicate(const void *P1, const void *P2) { - const ConstantInt *LHS = *(const ConstantInt*const*)P1; - const ConstantInt *RHS = *(const ConstantInt*const*)P2; +static int ConstantIntSortPredicate(ConstantInt *const *P1, + ConstantInt *const *P2) { + const ConstantInt *LHS = *P1; + const ConstantInt *RHS = *P2; if (LHS->getValue().ult(RHS->getValue())) return 1; if (LHS->getValue() == RHS->getValue()) diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 43de2be9776..f2eef4f68f5 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -813,9 +813,10 @@ static bool testSubClass(const CodeGenRegisterClass *A, /// Register classes with the same registers, spill size, and alignment form a /// clique. They will be ordered alphabetically. /// -static int TopoOrderRC(const void *PA, const void *PB) { - const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA; - const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB; +static int TopoOrderRC(CodeGenRegisterClass *const *PA, + CodeGenRegisterClass *const *PB) { + const CodeGenRegisterClass *A = *PA; + const CodeGenRegisterClass *B = *PB; if (A == B) return 0; diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp index 7fb7d65a704..cff004f5694 100644 --- a/utils/TableGen/OptParserEmitter.cpp +++ b/utils/TableGen/OptParserEmitter.cpp @@ -41,9 +41,9 @@ static int StrCmpOptionName(const char *A, const char *B) { return (a < b) ? -1 : 1; } -static int CompareOptionRecords(const void *Av, const void *Bv) { - const Record *A = *(const Record*const*) Av; - const Record *B = *(const Record*const*) Bv; +static int CompareOptionRecords(Record *const *Av, Record *const *Bv) { + const Record *A = *Av; + const Record *B = *Bv; // Sentinel options precede all others and are only ordered by precedence. bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel");