From: Justin Lebar Date: Thu, 29 Dec 2016 18:15:34 +0000 (+0000) Subject: [ADT] Use memcpy for type punning in MathExtras. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc13d2043fbaa3b4dc8353a87e86af6515151a08;p=llvm [ADT] Use memcpy for type punning in MathExtras. Summary: Previously we type-punned through a union, which is not safe. Reviewers: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D28161 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290715 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index dd835170c2c..77970f48711 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -547,23 +547,19 @@ inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) { /// BitsToDouble - This function takes a 64-bit integer and returns the bit /// equivalent double. inline double BitsToDouble(uint64_t Bits) { - union { - uint64_t L; - double D; - } T; - T.L = Bits; - return T.D; + double D; + static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); + memcpy(&D, &Bits, sizeof(Bits)); + return D; } /// BitsToFloat - This function takes a 32-bit integer and returns the bit /// equivalent float. inline float BitsToFloat(uint32_t Bits) { - union { - uint32_t I; - float F; - } T; - T.I = Bits; - return T.F; + float F; + static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); + memcpy(&F, &Bits, sizeof(Bits)); + return F; } /// DoubleToBits - This function takes a double and returns the bit @@ -571,12 +567,10 @@ inline float BitsToFloat(uint32_t Bits) { /// changes the bits of NaNs on some hosts, notably x86, so this /// routine cannot be used if these bits are needed. inline uint64_t DoubleToBits(double Double) { - union { - uint64_t L; - double D; - } T; - T.D = Double; - return T.L; + uint64_t Bits; + static_assert(sizeof(uint64_t) == sizeof(double), "Unexpected type sizes"); + memcpy(&Bits, &Double, sizeof(Double)); + return Bits; } /// FloatToBits - This function takes a float and returns the bit @@ -584,12 +578,10 @@ inline uint64_t DoubleToBits(double Double) { /// changes the bits of NaNs on some hosts, notably x86, so this /// routine cannot be used if these bits are needed. inline uint32_t FloatToBits(float Float) { - union { - uint32_t I; - float F; - } T; - T.F = Float; - return T.I; + uint32_t Bits; + static_assert(sizeof(uint32_t) == sizeof(float), "Unexpected type sizes"); + memcpy(&Bits, &Float, sizeof(Float)); + return Bits; } /// MinAlign - A and B are either alignments or offsets. Return the minimum