[llvm-commits] [compiler-rt] r171948 - in /compiler-rt/trunk/lib/ubsan: lit_tests/Misc/deduplication.cpp ubsan_handlers.cc ubsan_handlers_cxx.cc ubsan_value.h

Will Dietz wdietz2 at illinois.edu
Tue Jan 8 19:40:04 PST 2013


Author: wdietz2
Date: Tue Jan  8 21:40:03 2013
New Revision: 171948

URL: http://llvm.org/viewvc/llvm-project?rev=171948&view=rev
Log:
[ubsan] Add deduplication functionality, always enabled.

Added:
    compiler-rt/trunk/lib/ubsan/lit_tests/Misc/deduplication.cpp
Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
    compiler-rt/trunk/lib/ubsan/ubsan_value.h

Added: compiler-rt/trunk/lib/ubsan/lit_tests/Misc/deduplication.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/lit_tests/Misc/deduplication.cpp?rev=171948&view=auto
==============================================================================
--- compiler-rt/trunk/lib/ubsan/lit_tests/Misc/deduplication.cpp (added)
+++ compiler-rt/trunk/lib/ubsan/lit_tests/Misc/deduplication.cpp Tue Jan  8 21:40:03 2013
@@ -0,0 +1,25 @@
+// RUN: %clang -fsanitize=undefined %s -o %t && %t 2>&1 | FileCheck %s
+// Verify deduplication works by ensuring only one diag is emitted.
+#include <limits.h>
+#include <stdio.h>
+
+void overflow() {
+  int i = INT_MIN;
+  --i;
+}
+
+int main() {
+  // CHECK: Start
+  fprintf(stderr, "Start\n");
+
+  // CHECK: runtime error
+  // CHECK-NOT: runtime error
+  // CHECK-NOT: runtime error
+  overflow();
+  overflow();
+  overflow();
+
+  // CHECK: End
+  fprintf(stderr, "End\n");
+  return 0;
+}

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc?rev=171948&r1=171947&r2=171948&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Tue Jan  8 21:40:03 2013
@@ -28,7 +28,11 @@
 
 static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
                                    Location FallbackLoc) {
-  Location Loc = Data->Loc;
+  Location Loc = Data->Loc.acquire();
+
+  // Use the SourceLocation from Data to track deduplication, even if 'invalid'
+  if (Loc.getSourceLocation().isDisabled())
+    return;
   if (Data->Loc.isInvalid())
     Loc = FallbackLoc;
 
@@ -62,8 +66,12 @@
                                                        ValueHandle LHS,
                                                        const char *Operator,
                                                        T RHS) {
-  Diag(Data->Loc, DL_Error, "%0 integer overflow: "
-                            "%1 %2 %3 cannot be represented in type %4")
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
+  Diag(Loc, DL_Error, "%0 integer overflow: "
+                      "%1 %2 %3 cannot be represented in type %4")
     << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
     << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
 }
@@ -103,13 +111,17 @@
 
 void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,
                                              ValueHandle OldVal) {
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
   if (Data->Type.isSignedIntegerTy())
-    Diag(Data->Loc, DL_Error,
+    Diag(Loc, DL_Error,
          "negation of %0 cannot be represented in type %1; "
          "cast to an unsigned type to negate this value to itself")
       << Value(Data->Type, OldVal) << Data->Type;
   else
-    Diag(Data->Loc, DL_Error,
+    Diag(Loc, DL_Error,
          "negation of %0 cannot be represented in type %1")
       << Value(Data->Type, OldVal) << Data->Type;
 }
@@ -121,14 +133,18 @@
 
 void __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data,
                                              ValueHandle LHS, ValueHandle RHS) {
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
   Value LHSVal(Data->Type, LHS);
   Value RHSVal(Data->Type, RHS);
   if (RHSVal.isMinusOne())
-    Diag(Data->Loc, DL_Error,
+    Diag(Loc, DL_Error,
          "division of %0 by -1 cannot be represented in type %1")
       << LHSVal << Data->Type;
   else
-    Diag(Data->Loc, DL_Error, "division by zero");
+    Diag(Loc, DL_Error, "division by zero");
 }
 void __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,
                                                     ValueHandle LHS,
@@ -140,18 +156,22 @@
 void __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,
                                                  ValueHandle LHS,
                                                  ValueHandle RHS) {
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
   Value LHSVal(Data->LHSType, LHS);
   Value RHSVal(Data->RHSType, RHS);
   if (RHSVal.isNegative())
-    Diag(Data->Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
+    Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
   else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
-    Diag(Data->Loc, DL_Error,
+    Diag(Loc, DL_Error,
          "shift exponent %0 is too large for %1-bit type %2")
       << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
   else if (LHSVal.isNegative())
-    Diag(Data->Loc, DL_Error, "left shift of negative value %0") << LHSVal;
+    Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
   else
-    Diag(Data->Loc, DL_Error,
+    Diag(Loc, DL_Error,
          "left shift of %0 by %1 places cannot be represented in type %2")
       << LHSVal << RHSVal << Data->LHSType;
 }
@@ -177,8 +197,12 @@
 
 void __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data,
                                                     ValueHandle Bound) {
-  Diag(Data->Loc, DL_Error, "variable length array bound evaluates to "
-                            "non-positive value %0")
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
+  Diag(Loc, DL_Error, "variable length array bound evaluates to "
+                      "non-positive value %0")
     << Value(Data->Type, Bound);
 }
 void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
@@ -190,6 +214,7 @@
 
 void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
                                                  ValueHandle From) {
+  // TODO: Add deduplication once a SourceLocation is generated for this check.
   Diag(getCallerLocation(), DL_Error,
        "value %0 is outside the range of representable values of type %2")
     << Value(Data->FromType, From) << Data->FromType << Data->ToType;
@@ -205,6 +230,7 @@
 
 void __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data,
                                                 ValueHandle Val) {
+  // TODO: Add deduplication once a SourceLocation is generated for this check.
   Diag(getCallerLocation(), DL_Error,
        "load of value %0, which is not a valid value for type %1")
     << Value(Data->Type, Val) << Data->Type;

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc?rev=171948&r1=171947&r2=171948&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Tue Jan  8 21:40:03 2013
@@ -33,7 +33,11 @@
     // Just a cache miss. The type matches after all.
     return;
 
-  Diag(Data->Loc, DL_Error,
+  SourceLocation Loc = Data->Loc.acquire();
+  if (Loc.isDisabled())
+    return;
+
+  Diag(Loc, DL_Error,
        "%0 address %1 which does not point to an object of type %2")
     << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
 

Modified: compiler-rt/trunk/lib/ubsan/ubsan_value.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_value.h?rev=171948&r1=171947&r2=171948&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_value.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_value.h Tue Jan  8 21:40:03 2013
@@ -46,7 +46,6 @@
 /// \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 @@
   /// \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.





More information about the llvm-commits mailing list