Daily bump.
[official-gcc.git] / libsanitizer / ubsan / ubsan_value.h
blobe0957276dd241975aa6643d625c68b528522d192
1 //===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Representation of data which is passed from the compiler-generated calls into
10 // the ubsan runtime.
12 //===----------------------------------------------------------------------===//
13 #ifndef UBSAN_VALUE_H
14 #define UBSAN_VALUE_H
16 #include "sanitizer_common/sanitizer_atomic.h"
17 #include "sanitizer_common/sanitizer_common.h"
19 // FIXME: Move this out to a config header.
20 #if __SIZEOF_INT128__
21 __extension__ typedef __int128 s128;
22 __extension__ typedef unsigned __int128 u128;
23 #define HAVE_INT128_T 1
24 #else
25 #define HAVE_INT128_T 0
26 #endif
28 namespace __ubsan {
30 /// \brief Largest integer types we support.
31 #if HAVE_INT128_T
32 typedef s128 SIntMax;
33 typedef u128 UIntMax;
34 #else
35 typedef s64 SIntMax;
36 typedef u64 UIntMax;
37 #endif
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 {
45 const char *Filename;
46 u32 Line;
47 u32 Column;
49 public:
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.
68 bool isDisabled() {
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
84 /// have.
85 u16 TypeKind;
87 /// A \c Type-specific value providing information which allows us to
88 /// interpret the meaning of a ValueHandle of this type.
89 u16 TypeInfo;
91 /// The name of the type follows, in a format suitable for including in
92 /// diagnostics.
93 char TypeName[1];
95 public:
96 enum Kind {
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.
101 TK_Integer = 0x0000,
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
104 /// integer type.
105 TK_Float = 0x0001,
106 /// Any other type. The value representation is unspecified.
107 TK_Unknown = 0xffff
110 const char *getTypeName() const { return TypeName; }
112 Kind getKind() const {
113 return static_cast<Kind>(TypeKind);
116 bool isIntegerTy() const { return getKind() == TK_Integer; }
117 bool isSignedIntegerTy() const {
118 return isIntegerTy() && (TypeInfo & 1);
120 bool isUnsignedIntegerTy() const {
121 return isIntegerTy() && !(TypeInfo & 1);
123 unsigned getIntegerBitWidth() const {
124 CHECK(isIntegerTy());
125 return 1 << (TypeInfo >> 1);
128 bool isFloatTy() const { return getKind() == TK_Float; }
129 unsigned getFloatBitWidth() const {
130 CHECK(isFloatTy());
131 return TypeInfo;
135 /// \brief An opaque handle to a value.
136 typedef uptr ValueHandle;
138 /// Returns the class name of the given ObjC object, or null if the name
139 /// cannot be found.
140 const char *getObjCClassName(ValueHandle Pointer);
142 /// \brief Representation of an operand value provided by the instrumented code.
144 /// This is a combination of a TypeDescriptor (which is emitted as constant data
145 /// as an operand to a handler function) and a ValueHandle (which is passed at
146 /// runtime when a check failure occurs).
147 class Value {
148 /// The type of the value.
149 const TypeDescriptor &Type;
150 /// The encoded value itself.
151 ValueHandle Val;
153 /// Is \c Val a (zero-extended) integer?
154 bool isInlineInt() const {
155 CHECK(getType().isIntegerTy());
156 const unsigned InlineBits = sizeof(ValueHandle) * 8;
157 const unsigned Bits = getType().getIntegerBitWidth();
158 return Bits <= InlineBits;
161 /// Is \c Val a (zero-extended) integer representation of a float?
162 bool isInlineFloat() const {
163 CHECK(getType().isFloatTy());
164 const unsigned InlineBits = sizeof(ValueHandle) * 8;
165 const unsigned Bits = getType().getFloatBitWidth();
166 return Bits <= InlineBits;
169 public:
170 Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
172 const TypeDescriptor &getType() const { return Type; }
174 /// \brief Get this value as a signed integer.
175 SIntMax getSIntValue() const;
177 /// \brief Get this value as an unsigned integer.
178 UIntMax getUIntValue() const;
180 /// \brief Decode this value, which must be a positive or unsigned integer.
181 UIntMax getPositiveIntValue() const;
183 /// Is this an integer with value -1?
184 bool isMinusOne() const {
185 return getType().isSignedIntegerTy() && getSIntValue() == -1;
188 /// Is this a negative integer?
189 bool isNegative() const {
190 return getType().isSignedIntegerTy() && getSIntValue() < 0;
193 /// \brief Get this value as a floating-point quantity.
194 FloatMax getFloatValue() const;
197 } // namespace __ubsan
199 #endif // UBSAN_VALUE_H