ubsan_value.cc revision ba3fde65b900ce9d0ecdf034dfe3825eea810434
1//===-- ubsan_value.cc ----------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Representation of a runtime value, as marshaled from the generated code to 11// the ubsan runtime. 12// 13//===----------------------------------------------------------------------===// 14 15#include "ubsan_value.h" 16 17using namespace __ubsan; 18 19SIntMax Value::getSIntValue() const { 20 CHECK(getType().isSignedIntegerTy()); 21 if (isInlineInt()) { 22 // Val was zero-extended to ValueHandle. Sign-extend from original width 23 // to SIntMax. 24 const unsigned ExtraBits = 25 sizeof(SIntMax) * 8 - getType().getIntegerBitWidth(); 26 return SIntMax(Val) << ExtraBits >> ExtraBits; 27 } 28 if (getType().getIntegerBitWidth() == 64) 29 return *reinterpret_cast<s64*>(Val); 30#if HAVE_INT128_T 31 if (getType().getIntegerBitWidth() == 128) 32 return *reinterpret_cast<s128*>(Val); 33#endif 34 UNREACHABLE("unexpected bit width"); 35} 36 37UIntMax Value::getUIntValue() const { 38 CHECK(getType().isUnsignedIntegerTy()); 39 if (isInlineInt()) 40 return Val; 41 if (getType().getIntegerBitWidth() == 64) 42 return *reinterpret_cast<u64*>(Val); 43#if HAVE_INT128_T 44 if (getType().getIntegerBitWidth() == 128) 45 return *reinterpret_cast<u128*>(Val); 46#endif 47 UNREACHABLE("unexpected bit width"); 48} 49 50UIntMax Value::getPositiveIntValue() const { 51 if (getType().isUnsignedIntegerTy()) 52 return getUIntValue(); 53 SIntMax Val = getSIntValue(); 54 CHECK(Val >= 0); 55 return Val; 56} 57 58/// Get the floating-point value of this object, extended to a long double. 59/// These are always passed by address (our calling convention doesn't allow 60/// them to be passed in floating-point registers, so this has little cost). 61FloatMax Value::getFloatValue() const { 62 CHECK(getType().isFloatTy()); 63 switch (getType().getFloatBitWidth()) { 64#if 0 65 // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion 66 // from this to 'long double'. 67 case 16: return *reinterpret_cast<__fp16*>(Val); 68#endif 69 case 32: return *reinterpret_cast<float*>(Val); 70 case 64: return *reinterpret_cast<double*>(Val); 71 case 80: return *reinterpret_cast<long double*>(Val); 72 case 128: return *reinterpret_cast<long double*>(Val); 73 } 74 UNREACHABLE("unexpected floating point bit width"); 75} 76