summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-12-29 18:15:34 +0000
committerJustin Lebar <jlebar@google.com>2016-12-29 18:15:34 +0000
commit25eeb38acccb8150cbd4a4d2ed17c841d7c095a3 (patch)
tree77000e524b0c4337441ff85b91c604a7c666ef24
parentcd46c1df809836ebd9a862ee6be2ea68214e3bf8 (diff)
downloadbcm5719-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.h40
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
OpenPOWER on IntegriCloud