summaryrefslogtreecommitdiff
path: root/lib/ubsan/ubsan_value.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ubsan/ubsan_value.h')
-rw-r--r--lib/ubsan/ubsan_value.h20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/ubsan/ubsan_value.h b/lib/ubsan/ubsan_value.h
index 21313fc36..55a1ba921 100644
--- a/lib/ubsan/ubsan_value.h
+++ b/lib/ubsan/ubsan_value.h
@@ -46,7 +46,6 @@ typedef u64 UIntMax;
/// \brief Largest floating-point type we support.
typedef long double FloatMax;
-
/// \brief A description of a source location. This corresponds to Clang's
/// \c PresumedLoc type.
class SourceLocation {
@@ -62,6 +61,25 @@ public:
/// \brief Determine whether the source location is known.
bool isInvalid() const { return !Filename; }
+ /// \brief Atomically acquire a copy, disabling original in-place.
+ /// Exactly one call to acquire() returns a copy that isn't disabled.
+ SourceLocation acquire() {
+#ifdef __ATOMIC_RELAXED
+ // Use weaker ordering if available (relaxed/monotonic)
+ u32 OldColumn = __atomic_exchange_n(&Column, ~u32(0), __ATOMIC_RELAXED);
+#else
+ // Otherwise, do a TAS which has acquire semantics, stronger than needed.
+ u32 OldColumn = __sync_lock_test_and_set(&Column, ~u32(0));
+#endif
+ return SourceLocation(Filename, Line, OldColumn);
+ }
+
+ /// \brief Determine if this Location has been disabled.
+ /// Disabled SourceLocations are invalid to use.
+ bool isDisabled() {
+ return Column == ~u32(0);
+ }
+
/// \brief Get the presumed filename for the source location.
const char *getFilename() const { return Filename; }
/// \brief Get the presumed line number.