[llvm-commits] [compiler-rt] r169113 - in /compiler-rt/trunk/lib/ubsan: lit_tests/Integer/no-recover.cpp ubsan_handlers.cc ubsan_handlers.h ubsan_handlers_cxx.cc ubsan_handlers_cxx.h

Will Dietz wdietz2 at illinois.edu
Sun Dec 2 11:47:29 PST 2012


Author: wdietz2
Date: Sun Dec  2 13:47:29 2012
New Revision: 169113

URL: http://llvm.org/viewvc/llvm-project?rev=169113&view=rev
Log:
[ubsan] Refactor handlers to have separate entry points for aborting.

If user specifies aborting after a recoverable failed check is
appropriate, frontend should emit call to the _abort variant.

Test this behavior with newly added -fsanitize-recover flag.

Added:
    compiler-rt/trunk/lib/ubsan/lit_tests/Integer/no-recover.cpp
Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h

Added: compiler-rt/trunk/lib/ubsan/lit_tests/Integer/no-recover.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/lit_tests/Integer/no-recover.cpp?rev=169113&view=auto
==============================================================================
--- compiler-rt/trunk/lib/ubsan/lit_tests/Integer/no-recover.cpp (added)
+++ compiler-rt/trunk/lib/ubsan/lit_tests/Integer/no-recover.cpp Sun Dec  2 13:47:29 2012
@@ -0,0 +1,21 @@
+// RUN: %clang -fsanitize=unsigned-integer-overflow -Xclang -fsanitize-recover %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %clang -fsanitize=unsigned-integer-overflow %s -o %t && %t 2>&1 | FileCheck %s --check-prefix=ABORT
+
+#include <stdint.h>
+
+int main() {
+  // These promote to 'int'.
+  (void)(uint8_t(0xff) + uint8_t(0xff));
+  (void)(uint16_t(0xf0fff) + uint16_t(0x0fff));
+  // RECOVER-NOT: runtime error
+  // ABORT-NOT: runtime error
+
+  uint32_t k = 0x87654321;
+  k += 0xedcba987;
+  // RECOVER: no-recover.cpp:14:5: runtime error: unsigned integer overflow: 2271560481 + 3989547399 cannot be represented in type 'uint32_t' (aka 'unsigned int')
+  // ABORT: no-recover.cpp:14:5: runtime error: unsigned integer overflow: 2271560481 + 3989547399 cannot be represented in type 'uint32_t' (aka 'unsigned int')
+
+  (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
+  // RECOVER: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned long'
+  // ABORT-NOT: runtime error
+}

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=169113&r1=169112&r2=169113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Sun Dec  2 13:47:29 2012
@@ -40,6 +40,10 @@
     Diag(Data->Loc, "%0 address %1 with insufficient space "
                     "for an object of type %2")
       << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
+}
+void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,
+                                                  ValueHandle Pointer) {
+  __ubsan_handle_type_mismatch(Data, Pointer);
   Die();
 }
 
@@ -52,29 +56,50 @@
                   "%1 %2 %3 cannot be represented in type %4")
     << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
     << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
-  Die();
 }
 
 void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data,
                                           ValueHandle LHS, ValueHandle RHS) {
   HandleIntegerOverflow(Data, LHS, "+", Value(Data->Type, RHS));
 }
+void __ubsan::__ubsan_handle_add_overflow_abort(OverflowData *Data,
+                                                 ValueHandle LHS,
+                                                 ValueHandle RHS) {
+  __ubsan_handle_add_overflow(Data, LHS, RHS);
+  Die();
+}
 
 void __ubsan::__ubsan_handle_sub_overflow(OverflowData *Data,
                                           ValueHandle LHS, ValueHandle RHS) {
   HandleIntegerOverflow(Data, LHS, "-", Value(Data->Type, RHS));
 }
+void __ubsan::__ubsan_handle_sub_overflow_abort(OverflowData *Data,
+                                                 ValueHandle LHS,
+                                                 ValueHandle RHS) {
+  __ubsan_handle_sub_overflow(Data, LHS, RHS);
+  Die();
+}
 
 void __ubsan::__ubsan_handle_mul_overflow(OverflowData *Data,
                                           ValueHandle LHS, ValueHandle RHS) {
   HandleIntegerOverflow(Data, LHS, "*", Value(Data->Type, RHS));
 }
+void __ubsan::__ubsan_handle_mul_overflow_abort(OverflowData *Data,
+                                                 ValueHandle LHS,
+                                                 ValueHandle RHS) {
+  __ubsan_handle_mul_overflow(Data, LHS, RHS);
+  Die();
+}
 
 void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,
                                              ValueHandle OldVal) {
   Diag(Data->Loc, "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;
+}
+void __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data,
+                                                    ValueHandle OldVal) {
+  __ubsan_handle_negate_overflow(Data, OldVal);
   Die();
 }
 
@@ -87,6 +112,11 @@
       << LHSVal << Data->Type;
   else
     Diag(Data->Loc, "division by zero");
+}
+void __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,
+                                                    ValueHandle LHS,
+                                                    ValueHandle RHS) {
+  __ubsan_handle_divrem_overflow(Data, LHS, RHS);
   Die();
 }
 
@@ -105,6 +135,12 @@
   else
     Diag(Data->Loc, "left shift of %0 by %1 places cannot be represented "
                     "in type %2") << LHSVal << RHSVal << Data->LHSType;
+}
+void __ubsan::__ubsan_handle_shift_out_of_bounds_abort(
+                                                     ShiftOutOfBoundsData *Data,
+                                                     ValueHandle LHS,
+                                                     ValueHandle RHS) {
+  __ubsan_handle_shift_out_of_bounds(Data, LHS, RHS);
   Die();
 }
 
@@ -124,6 +160,10 @@
   Diag(Data->Loc, "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,
+                                                           ValueHandle Bound) {
+  __ubsan_handle_vla_bound_not_positive(Data, Bound);
   Die();
 }
 
@@ -132,5 +172,10 @@
   Diag(SourceLocation(), "value %0 is outside the range of representable "
                          "values of type %2")
     << Value(Data->FromType, From) << Data->FromType << Data->ToType;
+}
+void __ubsan::__ubsan_handle_float_cast_overflow_abort(
+                                                    FloatCastOverflowData *Data,
+                                                    ValueHandle From) {
+  __ubsan_handle_float_cast_overflow(Data, From);
   Die();
 }

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.h?rev=169113&r1=169112&r2=169113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.h Sun Dec  2 13:47:29 2012
@@ -24,11 +24,14 @@
   unsigned char TypeCheckKind;
 };
 
+#define RECOVERABLE(checkname, ...) \
+  extern "C" void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \
+  extern "C" void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ );
+
 /// \brief Handle a runtime type check failure, caused by either a misaligned
 /// pointer, a null pointer, or a pointer to insufficient storage for the
 /// type.
-extern "C" void __ubsan_handle_type_mismatch(TypeMismatchData *Data,
-                                             ValueHandle Pointer);
+RECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer)
 
 struct OverflowData {
   SourceLocation Loc;
@@ -36,24 +39,20 @@
 };
 
 /// \brief Handle an integer addition overflow.
-extern "C" void __ubsan_handle_add_overflow(OverflowData *Data,
-                                            ValueHandle LHS,
-                                            ValueHandle RHS);
+RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
 /// \brief Handle an integer subtraction overflow.
-extern "C" void __ubsan_handle_sub_overflow(OverflowData *Data,
-                                            ValueHandle LHS,
-                                            ValueHandle RHS);
+RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
 /// \brief Handle an integer multiplication overflow.
-extern "C" void __ubsan_handle_mul_overflow(OverflowData *Data,
-                                            ValueHandle LHS,
-                                            ValueHandle RHS);
+RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
 /// \brief Handle a signed integer overflow for a unary negate operator.
-extern "C" void __ubsan_handle_negate_overflow(OverflowData *Data,
-                                               ValueHandle OldVal);
+RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal)
+
 /// \brief Handle an INT_MIN/-1 overflow or division by zero.
-extern "C" void __ubsan_handle_divrem_overflow(OverflowData *Data,
-                                               ValueHandle LHS,
-                                               ValueHandle RHS);
+RECOVERABLE(divrem_overflow, OverflowData *Data,
+            ValueHandle LHS, ValueHandle RHS)
 
 struct ShiftOutOfBoundsData {
   SourceLocation Loc;
@@ -63,9 +62,8 @@
 
 /// \brief Handle a shift where the RHS is out of bounds or a left shift where
 /// the LHS is negative or overflows.
-extern "C" void __ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,
-                                                   ValueHandle LHS,
-                                                   ValueHandle RHS);
+RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data,
+            ValueHandle LHS, ValueHandle RHS)
 
 struct UnreachableData {
   SourceLocation Loc;
@@ -82,8 +80,7 @@
 };
 
 /// \brief Handle a VLA with a non-positive bound.
-extern "C" void __ubsan_handle_vla_bound_not_positive(VLABoundData *Data,
-                                                      ValueHandle Bound);
+RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)
 
 struct FloatCastOverflowData {
   // FIXME: SourceLocation Loc;
@@ -92,8 +89,7 @@
 };
 
 /// \brief Handle overflow in a conversion to or from a floating-point type.
-extern "C" void __ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
-                                                   ValueHandle From);
+RECOVERABLE(float_cast_overflow, FloatCastOverflowData *Data, ValueHandle From)
 
 }
 

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=169113&r1=169112&r2=169113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Sun Dec  2 13:47:29 2012
@@ -26,8 +26,9 @@
   extern const char *TypeCheckKinds[];
 }
 
-void __ubsan::__ubsan_handle_dynamic_type_cache_miss(
-  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
+static void HandleDynamicTypeCacheMiss(
+  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
+  bool abort) {
   if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))
     // Just a cache miss. The type matches after all.
     return;
@@ -45,5 +46,15 @@
   //   00 00 00 00  e0 f7 c5 09 00 00 00 00  20 00 00 00
   //                ^~~~~~~~~~~
   //                vptr for 'llvm::BinaryOperator'
-  Die();
+  if (abort)
+    Die();
+}
+
+void __ubsan::__ubsan_handle_dynamic_type_cache_miss(
+  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
+  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, false);
+}
+void __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(
+  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
+  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, true);
 }

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h?rev=169113&r1=169112&r2=169113&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h Sun Dec  2 13:47:29 2012
@@ -30,6 +30,8 @@
 /// cache; this does not necessarily imply the existence of a bug.
 extern "C" void __ubsan_handle_dynamic_type_cache_miss(
   DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+extern "C" void __ubsan_handle_dynamic_type_cache_miss_abort(
+  DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
 
 }
 





More information about the llvm-commits mailing list