diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index e6e72413da4..4e19b16f61a 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -245,20 +245,9 @@ public: }; template -struct ilist_traits > - : public ilist_default_traits > { - typedef SparseBitVectorElement Element; - - Element *createSentinel() const { return static_cast(&Sentinel); } - static void destroySentinel(Element *) {} - - Element *provideInitialHead() const { return createSentinel(); } - Element *ensureHead(Element *) const { return createSentinel(); } - static void noteHead(Element *, Element *) {} - -private: - mutable ilist_half_node Sentinel; -}; +struct ilist_sentinel_traits> + : public ilist_half_embedded_sentinel_traits< + SparseBitVectorElement> {}; template class SparseBitVector { diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 6744ddd6c9b..3a431bb9536 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -109,10 +109,11 @@ template class ilist_half_node; template class ilist_node; /// Traits with an embedded ilist_node as a sentinel. -/// -/// FIXME: The downcast in createSentinel() is UB. template struct ilist_embedded_sentinel_traits { /// Get hold of the node that marks the end of the list. + /// + /// FIXME: This downcast is UB. See llvm.org/PR26753. + LLVM_NO_SANITIZE("object-size") NodeTy *createSentinel() const { // Since i(p)lists always publicly derive from their corresponding traits, // placing a data member in this class will augment the i(p)list. But since @@ -134,10 +135,11 @@ private: }; /// Trait with an embedded ilist_half_node as a sentinel. -/// -/// FIXME: The downcast in createSentinel() is UB. template struct ilist_half_embedded_sentinel_traits { /// Get hold of the node that marks the end of the list. + /// + /// FIXME: This downcast is UB. See llvm.org/PR26753. + LLVM_NO_SANITIZE("object-size") NodeTy *createSentinel() const { // See comment in ilist_embedded_sentinel_traits::createSentinel(). return static_cast(&Sentinel); @@ -152,6 +154,20 @@ private: mutable ilist_half_node Sentinel; }; +/// Traits with an embedded full node as a sentinel. +template struct ilist_full_embedded_sentinel_traits { + /// Get hold of the node that marks the end of the list. + NodeTy *createSentinel() const { return &Sentinel; } + static void destroySentinel(NodeTy *) {} + + NodeTy *provideInitialHead() const { return createSentinel(); } + NodeTy *ensureHead(NodeTy *) const { return createSentinel(); } + static void noteHead(NodeTy *, NodeTy *) {} + +private: + mutable NodeTy Sentinel; +}; + /// ilist_node_traits - A fragment for template traits for intrusive list /// that provides default node related operations. /// diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 031085dddd2..16161be8db0 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -91,32 +91,9 @@ private: void deleted() override; }; -template<> struct ilist_traits - : public ilist_default_traits { - // createSentinel is used to get hold of a node that marks the end of - // the list... - // The sentinel is relative to this instance, so we use a non-static - // method. - IVStrideUse *createSentinel() const { - // since i(p)lists always publicly derive from the corresponding - // traits, placing a data member in this class will augment i(p)list. - // But since the NodeTy is expected to publicly derive from - // ilist_node, there is a legal viable downcast from it - // to NodeTy. We use this trick to superpose i(p)list with a "ghostly" - // NodeTy, which becomes the sentinel. Dereferencing the sentinel is - // forbidden (save the ilist_node) so no one will ever notice - // the superposition. - return static_cast(&Sentinel); - } - static void destroySentinel(IVStrideUse*) {} - - IVStrideUse *provideInitialHead() const { return createSentinel(); } - IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); } - static void noteHead(IVStrideUse*, IVStrideUse*) {} - -private: - mutable ilist_node Sentinel; -}; +template <> +struct ilist_sentinel_traits + : public ilist_embedded_sentinel_traits {}; class IVUsers { friend class IVStrideUse; diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 2923371c100..37a7948c9ef 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -38,25 +38,18 @@ class MachineBranchProbabilityInfo; // Forward declaration to avoid circular include problem with TargetRegisterInfo typedef unsigned LaneBitmask; +template <> +struct ilist_sentinel_traits + : public ilist_half_embedded_sentinel_traits {}; + template <> struct ilist_traits : public ilist_default_traits { private: - mutable ilist_half_node Sentinel; - // this is only set by the MachineBasicBlock owning the LiveList friend class MachineBasicBlock; MachineBasicBlock* Parent; public: - MachineInstr *createSentinel() const { - return static_cast(&Sentinel); - } - void destroySentinel(MachineInstr *) const {} - - MachineInstr *provideInitialHead() const { return createSentinel(); } - MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); } - static void noteHead(MachineInstr*, MachineInstr*) {} - void addNodeToList(MachineInstr* N); void removeNodeFromList(MachineInstr* N); void transferNodesFromList(ilist_traits &SrcTraits, diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h index f4c3b5c9ebb..533d659d78b 100644 --- a/include/llvm/CodeGen/MachineFunction.h +++ b/include/llvm/CodeGen/MachineFunction.h @@ -48,24 +48,13 @@ class TargetRegisterClass; struct MachinePointerInfo; struct WinEHFuncInfo; +template <> +struct ilist_sentinel_traits + : public ilist_half_embedded_sentinel_traits {}; + template <> struct ilist_traits : public ilist_default_traits { - mutable ilist_half_node Sentinel; -public: - // FIXME: This downcast is UB. See llvm.org/PR26753. - LLVM_NO_SANITIZE("object-size") - MachineBasicBlock *createSentinel() const { - return static_cast(&Sentinel); - } - void destroySentinel(MachineBasicBlock *) const {} - - MachineBasicBlock *provideInitialHead() const { return createSentinel(); } - MachineBasicBlock *ensureHead(MachineBasicBlock*) const { - return createSentinel(); - } - static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {} - void addNodeToList(MachineBasicBlock* MBB); void removeNodeFromList(MachineBasicBlock* MBB); void deleteNode(MachineBasicBlock *MBB); diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 29cce873c2f..8a89249e92a 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -81,19 +81,11 @@ template<> struct FoldingSetTrait : DefaultFoldingSetTrait struct ilist_traits : public ilist_default_traits { -private: - mutable ilist_half_node Sentinel; -public: - SDNode *createSentinel() const { - return static_cast(&Sentinel); - } - static void destroySentinel(SDNode *) {} - - SDNode *provideInitialHead() const { return createSentinel(); } - SDNode *ensureHead(SDNode*) const { return createSentinel(); } - static void noteHead(SDNode*, SDNode*) {} +template <> +struct ilist_sentinel_traits + : public ilist_half_embedded_sentinel_traits {}; +template <> struct ilist_traits : public ilist_default_traits { static void deleteNode(SDNode *) { llvm_unreachable("ilist_traits shouldn't see a deleteNode call!"); } diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 01184dc39b3..6090ecec32a 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -69,18 +69,12 @@ namespace llvm { }; template <> - struct ilist_traits : public ilist_default_traits { - private: - mutable ilist_half_node Sentinel; - public: - IndexListEntry *createSentinel() const { - return static_cast(&Sentinel); - } - void destroySentinel(IndexListEntry *) const {} + struct ilist_sentinel_traits + : public ilist_half_embedded_sentinel_traits {}; - IndexListEntry *provideInitialHead() const { return createSentinel(); } - IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); } - static void noteHead(IndexListEntry*, IndexListEntry*) {} + template <> + struct ilist_traits + : public ilist_default_traits { void deleteNode(IndexListEntry *N) {} private: diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index 632b27e2d0d..ef7e4074176 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -37,23 +37,14 @@ class RandomNumberGenerator; class StructType; template class SmallPtrSetImpl; +template <> +struct ilist_sentinel_traits + : public ilist_embedded_sentinel_traits {}; + template<> struct ilist_traits : public ilist_default_traits { - // createSentinel is used to get hold of a node that marks the end of - // the list... - NamedMDNode *createSentinel() const { - return static_cast(&Sentinel); - } - static void destroySentinel(NamedMDNode*) {} - - NamedMDNode *provideInitialHead() const { return createSentinel(); } - NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); } - static void noteHead(NamedMDNode*, NamedMDNode*) {} void addNodeToList(NamedMDNode *) {} void removeNodeFromList(NamedMDNode *) {} - -private: - mutable ilist_node Sentinel; }; /// A Module instance is used to store all the information related to an diff --git a/include/llvm/Transforms/Utils/MemorySSA.h b/include/llvm/Transforms/Utils/MemorySSA.h index 2caa63feec6..606ecff59c5 100644 --- a/include/llvm/Transforms/Utils/MemorySSA.h +++ b/include/llvm/Transforms/Utils/MemorySSA.h @@ -171,23 +171,8 @@ private: }; template <> -struct ilist_traits : public ilist_default_traits { - /// See details of the instruction class for why this trick works - // FIXME: This downcast is UB. See llvm.org/PR26753. - LLVM_NO_SANITIZE("object-size") - MemoryAccess *createSentinel() const { - return static_cast(&Sentinel); - } - - static void destroySentinel(MemoryAccess *) {} - - MemoryAccess *provideInitialHead() const { return createSentinel(); } - MemoryAccess *ensureHead(MemoryAccess *) const { return createSentinel(); } - static void noteHead(MemoryAccess *, MemoryAccess *) {} - -private: - mutable ilist_half_node Sentinel; -}; +struct ilist_sentinel_traits + : public ilist_half_embedded_sentinel_traits {}; inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) { MA.print(OS); diff --git a/lib/Support/YAMLParser.cpp b/lib/Support/YAMLParser.cpp index 2b71c596cc4..4d5b750e266 100644 --- a/lib/Support/YAMLParser.cpp +++ b/lib/Support/YAMLParser.cpp @@ -149,20 +149,9 @@ struct Token : ilist_node { } namespace llvm { -template<> -struct ilist_sentinel_traits { - Token *createSentinel() const { - return &Sentinel; - } - static void destroySentinel(Token*) {} - - Token *provideInitialHead() const { return createSentinel(); } - Token *ensureHead(Token*) const { return createSentinel(); } - static void noteHead(Token*, Token*) {} - -private: - mutable Token Sentinel; -}; +template <> +struct ilist_sentinel_traits + : public ilist_full_embedded_sentinel_traits {}; template<> struct ilist_node_traits {