From: Alexey Samsonov Date: Fri, 9 Jan 2015 23:17:25 +0000 (+0000) Subject: Fix UBSan error reports in ValueMapCallbackVH and AssertingVH empty/tombstone... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=f79e2d40b278bf9d1f52dcb46035fc7aa453639f;p=oota-llvm.git Fix UBSan error reports in ValueMapCallbackVH and AssertingVH empty/tombstone keys generation. Summary: One more attempt to fix UBSan reports: make sure DenseMapInfo::getEmptyKey() and DenseMapInfo::getTombstoneKey() doesn't do any upcasts/downcasts to/from Value*. Test Plan: check-llvm test suite with/without UBSan bootstrap Reviewers: chandlerc, dexonsmith Subscribers: llvm-commits, majnemer Differential Revision: http://reviews.llvm.org/D6903 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225558 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index 9bd14cf2253..8fc7fdb0395 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -190,23 +190,20 @@ class AssertingVH friend struct DenseMapInfo >; #ifndef NDEBUG - ValueTy *getValPtr() const { - return static_cast(ValueHandleBase::getValPtr()); - } - void setValPtr(ValueTy *P) { - ValueHandleBase::operator=(GetAsValue(P)); - } + Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); } + void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); } #else - ValueTy *ThePtr; - ValueTy *getValPtr() const { return ThePtr; } - void setValPtr(ValueTy *P) { ThePtr = P; } + Value *ThePtr; + Value *getRawValPtr() const { return ThePtr; } + void setRawValPtr(Value *P) { ThePtr = P; } #endif - - // Convert a ValueTy*, which may be const, to the type the base - // class expects. + // Convert a ValueTy*, which may be const, to the raw Value*. static Value *GetAsValue(Value *V) { return V; } static Value *GetAsValue(const Value *V) { return const_cast(V); } + ValueTy *getValPtr() const { return static_cast(getRawValPtr()); } + void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); } + public: #ifndef NDEBUG AssertingVH() : ValueHandleBase(Assert) {} @@ -214,7 +211,7 @@ public: AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {} #else AssertingVH() : ThePtr(nullptr) {} - AssertingVH(ValueTy *P) : ThePtr(P) {} + AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {} #endif operator ValueTy*() const { @@ -237,27 +234,23 @@ public: // Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. template struct DenseMapInfo > { - typedef DenseMapInfo PointerInfo; static inline AssertingVH getEmptyKey() { - return AssertingVH(PointerInfo::getEmptyKey()); + AssertingVH Res; + Res.setRawValPtr(DenseMapInfo::getEmptyKey()); + return Res; } - static inline T* getTombstoneKey() { - return AssertingVH(PointerInfo::getTombstoneKey()); + static inline AssertingVH getTombstoneKey() { + AssertingVH Res; + Res.setRawValPtr(DenseMapInfo::getTombstoneKey()); + return Res; } static unsigned getHashValue(const AssertingVH &Val) { - return PointerInfo::getHashValue(Val); + return DenseMapInfo::getHashValue(Val.getRawValPtr()); } -#ifndef NDEBUG static bool isEqual(const AssertingVH &LHS, const AssertingVH &RHS) { - // Avoid downcasting AssertingVH to T*, as empty/tombstone keys may not - // be properly aligned pointers to T*. - return LHS.ValueHandleBase::getValPtr() == RHS.ValueHandleBase::getValPtr(); + return DenseMapInfo::isEqual(LHS.getRawValPtr(), + RHS.getRawValPtr()); } -#else - static bool isEqual(const AssertingVH &LHS, const AssertingVH &RHS) { - return LHS == RHS; - } -#endif }; template diff --git a/include/llvm/IR/ValueMap.h b/include/llvm/IR/ValueMap.h index 9999113e099..f2ea405f142 100644 --- a/include/llvm/IR/ValueMap.h +++ b/include/llvm/IR/ValueMap.h @@ -224,6 +224,9 @@ class ValueMapCallbackVH : public CallbackVH { : CallbackVH(const_cast(static_cast(Key))), Map(Map) {} + // Private constructor used to create empty/tombstone DenseMap keys. + ValueMapCallbackVH(Value *V) : CallbackVH(V), Map(nullptr) {} + public: KeyT Unwrap() const { return cast_or_null(getValPtr()); } @@ -266,19 +269,18 @@ public: template struct DenseMapInfo > { typedef ValueMapCallbackVH VH; - typedef DenseMapInfo PointerInfo; static inline VH getEmptyKey() { - return VH(PointerInfo::getEmptyKey(), nullptr); + return VH(DenseMapInfo::getEmptyKey()); } static inline VH getTombstoneKey() { - return VH(PointerInfo::getTombstoneKey(), nullptr); + return VH(DenseMapInfo::getTombstoneKey()); } static unsigned getHashValue(const VH &Val) { - return PointerInfo::getHashValue(Val.Unwrap()); + return DenseMapInfo::getHashValue(Val.Unwrap()); } static unsigned getHashValue(const KeyT &Val) { - return PointerInfo::getHashValue(Val); + return DenseMapInfo::getHashValue(Val); } static bool isEqual(const VH &LHS, const VH &RHS) { return LHS == RHS;