1 //===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Representation of data which is passed from the compiler-generated calls into
13 //===----------------------------------------------------------------------===//
17 #include "sanitizer_common/sanitizer_atomic.h"
18 #include "sanitizer_common/sanitizer_common.h"
20 // FIXME: Move this out to a config header.
22 __extension__ typedef __int128 s128;
23 __extension__ typedef unsigned __int128 u128;
24 #define HAVE_INT128_T 1
26 #define HAVE_INT128_T 0
31 /// \brief Largest integer types we support.
40 /// \brief Largest floating-point type we support.
41 typedef long double FloatMax;
43 /// \brief A description of a source location. This corresponds to Clang's
44 /// \c PresumedLoc type.
45 class SourceLocation {
51 SourceLocation() : Filename(), Line(), Column() {}
52 SourceLocation(const char *Filename, unsigned Line, unsigned Column)
53 : Filename(Filename), Line(Line), Column(Column) {}
55 /// \brief Determine whether the source location is known.
56 bool isInvalid() const { return !Filename; }
58 /// \brief Atomically acquire a copy, disabling original in-place.
59 /// Exactly one call to acquire() returns a copy that isn't disabled.
60 SourceLocation acquire() {
61 u32 OldColumn = __sanitizer::atomic_exchange(
62 (__sanitizer::atomic_uint32_t *)&Column, ~u32(0),
63 __sanitizer::memory_order_relaxed);
64 return SourceLocation(Filename, Line, OldColumn);
67 /// \brief Determine if this Location has been disabled.
68 /// Disabled SourceLocations are invalid to use.
70 return Column == ~u32(0);
73 /// \brief Get the presumed filename for the source location.
74 const char *getFilename() const { return Filename; }
75 /// \brief Get the presumed line number.
76 unsigned getLine() const { return Line; }
77 /// \brief Get the column within the presumed line.
78 unsigned getColumn() const { return Column; }
82 /// \brief A description of a type.
83 class TypeDescriptor {
84 /// A value from the \c Kind enumeration, specifying what flavor of type we
88 /// A \c Type-specific value providing information which allows us to
89 /// interpret the meaning of a ValueHandle of this type.
92 /// The name of the type follows, in a format suitable for including in
98 /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
99 /// value. Remaining bits are log_2(bit width). The value representation is
100 /// the integer itself if it fits into a ValueHandle, and a pointer to the
101 /// integer otherwise.
103 /// A floating-point type. Low 16 bits are bit width. The value
104 /// representation is that of bitcasting the floating-point value to an
107 /// Any other type. The value representation is unspecified.
111 const char *getTypeName() const { return TypeName; }
113 Kind getKind() const {
114 return static_cast<Kind>(TypeKind);
117 bool isIntegerTy() const { return getKind() == TK_Integer; }
118 bool isSignedIntegerTy() const {
119 return isIntegerTy() && (TypeInfo & 1);
121 bool isUnsignedIntegerTy() const {
122 return isIntegerTy() && !(TypeInfo & 1);
124 unsigned getIntegerBitWidth() const {
125 CHECK(isIntegerTy());
126 return 1 << (TypeInfo >> 1);
129 bool isFloatTy() const { return getKind() == TK_Float; }
130 unsigned getFloatBitWidth() const {
136 /// \brief An opaque handle to a value.
137 typedef uptr ValueHandle;
140 /// \brief Representation of an operand value provided by the instrumented code.
142 /// This is a combination of a TypeDescriptor (which is emitted as constant data
143 /// as an operand to a handler function) and a ValueHandle (which is passed at
144 /// runtime when a check failure occurs).
146 /// The type of the value.
147 const TypeDescriptor &Type;
148 /// The encoded value itself.
151 /// Is \c Val a (zero-extended) integer?
152 bool isInlineInt() const {
153 CHECK(getType().isIntegerTy());
154 const unsigned InlineBits = sizeof(ValueHandle) * 8;
155 const unsigned Bits = getType().getIntegerBitWidth();
156 return Bits <= InlineBits;
159 /// Is \c Val a (zero-extended) integer representation of a float?
160 bool isInlineFloat() const {
161 CHECK(getType().isFloatTy());
162 const unsigned InlineBits = sizeof(ValueHandle) * 8;
163 const unsigned Bits = getType().getFloatBitWidth();
164 return Bits <= InlineBits;
168 Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
170 const TypeDescriptor &getType() const { return Type; }
172 /// \brief Get this value as a signed integer.
173 SIntMax getSIntValue() const;
175 /// \brief Get this value as an unsigned integer.
176 UIntMax getUIntValue() const;
178 /// \brief Decode this value, which must be a positive or unsigned integer.
179 UIntMax getPositiveIntValue() const;
181 /// Is this an integer with value -1?
182 bool isMinusOne() const {
183 return getType().isSignedIntegerTy() && getSIntValue() == -1;
186 /// Is this a negative integer?
187 bool isNegative() const {
188 return getType().isSignedIntegerTy() && getSIntValue() < 0;
191 /// \brief Get this value as a floating-point quantity.
192 FloatMax getFloatValue() const;
195 } // namespace __ubsan
197 #endif // UBSAN_VALUE_H