1 //===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Representation of data which is passed from the compiler-generated calls into
12 //===----------------------------------------------------------------------===//
16 #include "sanitizer_common/sanitizer_atomic.h"
17 #include "sanitizer_common/sanitizer_common.h"
19 // FIXME: Move this out to a config header.
21 __extension__
typedef __int128 s128
;
22 __extension__
typedef unsigned __int128 u128
;
23 #define HAVE_INT128_T 1
25 #define HAVE_INT128_T 0
30 /// \brief Largest integer types we support.
39 /// \brief Largest floating-point type we support.
40 typedef long double FloatMax
;
42 /// \brief A description of a source location. This corresponds to Clang's
43 /// \c PresumedLoc type.
44 class SourceLocation
{
50 SourceLocation() : Filename(), Line(), Column() {}
51 SourceLocation(const char *Filename
, unsigned Line
, unsigned Column
)
52 : Filename(Filename
), Line(Line
), Column(Column
) {}
54 /// \brief Determine whether the source location is known.
55 bool isInvalid() const { return !Filename
; }
57 /// \brief Atomically acquire a copy, disabling original in-place.
58 /// Exactly one call to acquire() returns a copy that isn't disabled.
59 SourceLocation
acquire() {
60 u32 OldColumn
= __sanitizer::atomic_exchange(
61 (__sanitizer::atomic_uint32_t
*)&Column
, ~u32(0),
62 __sanitizer::memory_order_relaxed
);
63 return SourceLocation(Filename
, Line
, OldColumn
);
66 /// \brief Determine if this Location has been disabled.
67 /// Disabled SourceLocations are invalid to use.
69 return Column
== ~u32(0);
72 /// \brief Get the presumed filename for the source location.
73 const char *getFilename() const { return Filename
; }
74 /// \brief Get the presumed line number.
75 unsigned getLine() const { return Line
; }
76 /// \brief Get the column within the presumed line.
77 unsigned getColumn() const { return Column
; }
81 /// \brief A description of a type.
82 class TypeDescriptor
{
83 /// A value from the \c Kind enumeration, specifying what flavor of type we
87 /// A \c Type-specific value providing information which allows us to
88 /// interpret the meaning of a ValueHandle of this type.
91 /// The name of the type follows, in a format suitable for including in
97 /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
98 /// value. Remaining bits are log_2(bit width). The value representation is
99 /// the integer itself if it fits into a ValueHandle, and a pointer to the
100 /// integer otherwise.
102 /// A floating-point type. Low 16 bits are bit width. The value
103 /// representation is that of bitcasting the floating-point value to an
106 /// An _BitInt(N) type. Lowest bit is 1 for a signed value, 0 for an
107 /// unsigned value. Remaining bits are log_2(bit_width). The value
108 /// representation is the integer itself if it fits into a ValueHandle, and
109 /// a pointer to the integer otherwise. TypeName contains the true width
110 /// of the type for the signed _BitInt(N) type stored after zero bit after
111 /// TypeName as 32-bit unsigned integer.
113 /// Any other type. The value representation is unspecified.
117 const char *getTypeName() const { return TypeName
; }
119 Kind
getKind() const {
120 return static_cast<Kind
>(TypeKind
);
123 bool isIntegerTy() const {
124 return getKind() == TK_Integer
|| getKind() == TK_BitInt
;
126 bool isBitIntTy() const { return getKind() == TK_BitInt
; }
128 bool isSignedIntegerTy() const {
129 return isIntegerTy() && (TypeInfo
& 1);
131 bool isSignedBitIntTy() const { return isBitIntTy() && (TypeInfo
& 1); }
132 bool isUnsignedIntegerTy() const {
133 return isIntegerTy() && !(TypeInfo
& 1);
135 unsigned getIntegerBitWidth() const {
136 CHECK(isIntegerTy());
137 return 1 << (TypeInfo
>> 1);
140 const char *getBitIntBitCountPointer() const {
141 DCHECK(isBitIntTy());
142 DCHECK(isSignedBitIntTy());
143 // Scan Name for zero and return the next address
144 const char *p
= getTypeName();
147 // Return the next address
151 unsigned getIntegerBitCount() const {
152 DCHECK(isIntegerTy());
153 if (isSignedBitIntTy())
154 return *reinterpret_cast<const u32
*>(getBitIntBitCountPointer());
156 return getIntegerBitWidth();
159 bool isFloatTy() const { return getKind() == TK_Float
; }
160 unsigned getFloatBitWidth() const {
166 /// \brief An opaque handle to a value.
167 typedef uptr ValueHandle
;
169 /// Returns the class name of the given ObjC object, or null if the name
171 const char *getObjCClassName(ValueHandle Pointer
);
173 /// \brief Representation of an operand value provided by the instrumented code.
175 /// This is a combination of a TypeDescriptor (which is emitted as constant data
176 /// as an operand to a handler function) and a ValueHandle (which is passed at
177 /// runtime when a check failure occurs).
179 /// The type of the value.
180 const TypeDescriptor
&Type
;
181 /// The encoded value itself.
184 /// Is \c Val a (zero-extended) integer?
185 bool isInlineInt() const {
186 CHECK(getType().isIntegerTy());
187 const unsigned InlineBits
= sizeof(ValueHandle
) * 8;
188 const unsigned Bits
= getType().getIntegerBitWidth();
189 return Bits
<= InlineBits
;
192 /// Is \c Val a (zero-extended) integer representation of a float?
193 bool isInlineFloat() const {
194 CHECK(getType().isFloatTy());
195 const unsigned InlineBits
= sizeof(ValueHandle
) * 8;
196 const unsigned Bits
= getType().getFloatBitWidth();
197 return Bits
<= InlineBits
;
201 Value(const TypeDescriptor
&Type
, ValueHandle Val
) : Type(Type
), Val(Val
) {}
203 const TypeDescriptor
&getType() const { return Type
; }
205 /// \brief Get this value as a signed integer.
206 SIntMax
getSIntValue() const;
208 /// \brief Get this value as an unsigned integer.
209 UIntMax
getUIntValue() const;
211 /// \brief Decode this value, which must be a positive or unsigned integer.
212 UIntMax
getPositiveIntValue() const;
214 /// Is this an integer with value -1?
215 bool isMinusOne() const {
216 return getType().isSignedIntegerTy() && getSIntValue() == -1;
219 /// Is this a negative integer?
220 bool isNegative() const {
221 return getType().isSignedIntegerTy() && getSIntValue() < 0;
224 /// \brief Get this value as a floating-point quantity.
225 FloatMax
getFloatValue() const;
228 } // namespace __ubsan
230 #endif // UBSAN_VALUE_H