diff options
author | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
commit | 1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch) | |
tree | c607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/libsanitizer/ubsan/ubsan_value.cc | |
parent | 283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff) | |
download | toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2 toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip |
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/libsanitizer/ubsan/ubsan_value.cc')
-rw-r--r-- | gcc-4.9/libsanitizer/ubsan/ubsan_value.cc | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/gcc-4.9/libsanitizer/ubsan/ubsan_value.cc b/gcc-4.9/libsanitizer/ubsan/ubsan_value.cc new file mode 100644 index 000000000..141e8b535 --- /dev/null +++ b/gcc-4.9/libsanitizer/ubsan/ubsan_value.cc @@ -0,0 +1,99 @@ +//===-- ubsan_value.cc ----------------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Representation of a runtime value, as marshaled from the generated code to +// the ubsan runtime. +// +//===----------------------------------------------------------------------===// + +#include "ubsan_value.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_libc.h" + +using namespace __ubsan; + +SIntMax Value::getSIntValue() const { + CHECK(getType().isSignedIntegerTy()); + if (isInlineInt()) { + // Val was zero-extended to ValueHandle. Sign-extend from original width + // to SIntMax. + const unsigned ExtraBits = + sizeof(SIntMax) * 8 - getType().getIntegerBitWidth(); + return SIntMax(Val) << ExtraBits >> ExtraBits; + } + if (getType().getIntegerBitWidth() == 64) + return *reinterpret_cast<s64*>(Val); +#if HAVE_INT128_T + if (getType().getIntegerBitWidth() == 128) + return *reinterpret_cast<s128*>(Val); +#else + if (getType().getIntegerBitWidth() == 128) + UNREACHABLE("libclang_rt.ubsan was built without __int128 support"); +#endif + UNREACHABLE("unexpected bit width"); +} + +UIntMax Value::getUIntValue() const { + CHECK(getType().isUnsignedIntegerTy()); + if (isInlineInt()) + return Val; + if (getType().getIntegerBitWidth() == 64) + return *reinterpret_cast<u64*>(Val); +#if HAVE_INT128_T + if (getType().getIntegerBitWidth() == 128) + return *reinterpret_cast<u128*>(Val); +#else + if (getType().getIntegerBitWidth() == 128) + UNREACHABLE("libclang_rt.ubsan was built without __int128 support"); +#endif + UNREACHABLE("unexpected bit width"); +} + +UIntMax Value::getPositiveIntValue() const { + if (getType().isUnsignedIntegerTy()) + return getUIntValue(); + SIntMax Val = getSIntValue(); + CHECK(Val >= 0); + return Val; +} + +/// Get the floating-point value of this object, extended to a long double. +/// These are always passed by address (our calling convention doesn't allow +/// them to be passed in floating-point registers, so this has little cost). +FloatMax Value::getFloatValue() const { + CHECK(getType().isFloatTy()); + if (isInlineFloat()) { + switch (getType().getFloatBitWidth()) { +#if 0 + // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion + // from '__fp16' to 'long double'. + case 16: { + __fp16 Value; + internal_memcpy(&Value, &Val, 4); + return Value; + } +#endif + case 32: { + float Value; + internal_memcpy(&Value, &Val, 4); + return Value; + } + case 64: { + double Value; + internal_memcpy(&Value, &Val, 8); + return Value; + } + } + } else { + switch (getType().getFloatBitWidth()) { + case 64: return *reinterpret_cast<double*>(Val); + case 80: return *reinterpret_cast<long double*>(Val); + case 128: return *reinterpret_cast<long double*>(Val); + } + } + UNREACHABLE("unexpected floating point bit width"); +} |