diff options
| author | Justin Lebar <jlebar@google.com> | 2016-12-29 18:15:34 +0000 |
|---|---|---|
| committer | Justin Lebar <jlebar@google.com> | 2016-12-29 18:15:34 +0000 |
| commit | 25eeb38acccb8150cbd4a4d2ed17c841d7c095a3 (patch) | |
| tree | 77000e524b0c4337441ff85b91c604a7c666ef24 | |
| parent | cd46c1df809836ebd9a862ee6be2ea68214e3bf8 (diff) | |
| download | bcm5719-llvm-25eeb38acccb8150cbd4a4d2ed17c841d7c095a3.tar.gz bcm5719-llvm-25eeb38acccb8150cbd4a4d2ed17c841d7c095a3.zip | |
[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
llvm-svn: 290715
| -rw-r--r-- | llvm/include/llvm/Support/MathExtras.h | 40 |
1 files changed, 16 insertions, 24 deletions
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h index dd835170c2c..77970f48711 100644 --- a/llvm/include/llvm/Support/MathExtras.h +++ b/llvm/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 |

