summaryrefslogtreecommitdiff
path: root/lib/ubsan
diff options
context:
space:
mode:
authorFilipe Cabecinhas <me@filcab.net>2015-08-11 04:19:24 +0000
committerFilipe Cabecinhas <me@filcab.net>2015-08-11 04:19:24 +0000
commitf4a7ee486c3a44f299893086a377111ce6db584a (patch)
tree5d022cd8eac9b6226cbf52887b8f8d71598ccb71 /lib/ubsan
parentcdcc390023f3a02b037d77dc512400fc4789915a (diff)
[compiler-rt] Add SourceLocations for float_cast_overflow data.
Summary: Compiler-rt part of http://reviews.llvm.org/D11757 I ended up making UBSan work with both the old version and the new version of the float_cast_overflow data (instead of just erroring with the previous version). The old version will try to symbolize its caller. Now we compile the float_cast_overflow tests without -g, and make sure we have the source file+line+column. If you think I'm trying too hard to make sure we can still use both versions, let me know. Reviewers: samsonov, rsmith Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11793 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@244567 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ubsan')
-rw-r--r--lib/ubsan/ubsan_handlers.cc53
-rw-r--r--lib/ubsan/ubsan_handlers.h14
2 files changed, 53 insertions, 14 deletions
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index a65b2f5e3..1e8fee355 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -290,26 +290,57 @@ void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
Die();
}
-static void handleFloatCastOverflow(FloatCastOverflowData *Data,
- ValueHandle From, ReportOptions Opts) {
- // TODO: Add deduplication once a SourceLocation is generated for this check.
- SymbolizedStackHolder CallerLoc(getCallerLocation(Opts.pc));
- Location Loc = CallerLoc;
+static bool looksLikeFloatCastOverflowDataV1(void *Data) {
+ // First field is either a pointer to filename or a pointer to a
+ // TypeDescriptor.
+ u8 *FilenameOrTypeDescriptor;
+ internal_memcpy(&FilenameOrTypeDescriptor, Data,
+ sizeof(FilenameOrTypeDescriptor));
+
+ // Heuristic: For float_cast_overflow, the TypeKind will be either TK_Integer
+ // (0x0) or TK_Float (0x1). Adding both bytes will be 0 or 1 (for BE or LE).
+ // If it were a filename, adding two printable characters will not yield such
+ // a value.
+ u16 MaybeFromTypeKind =
+ FilenameOrTypeDescriptor[0] + FilenameOrTypeDescriptor[1];
+ return MaybeFromTypeKind < 2;
+}
+
+static void handleFloatCastOverflow(void *DataPtr, ValueHandle From,
+ ReportOptions Opts) {
+ SymbolizedStackHolder CallerLoc;
+ Location Loc;
+ const TypeDescriptor *FromType, *ToType;
+
+ if (looksLikeFloatCastOverflowDataV1(DataPtr)) {
+ auto Data = reinterpret_cast<FloatCastOverflowData *>(DataPtr);
+ CallerLoc.reset(getCallerLocation(Opts.pc));
+ Loc = CallerLoc;
+ FromType = &Data->FromType;
+ ToType = &Data->ToType;
+ } else {
+ auto Data = reinterpret_cast<FloatCastOverflowDataV2 *>(DataPtr);
+ SourceLocation SLoc = Data->Loc.acquire();
+ if (ignoreReport(SLoc, Opts))
+ return;
+ Loc = SLoc;
+ FromType = &Data->FromType;
+ ToType = &Data->ToType;
+ }
+
ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error,
"value %0 is outside the range of representable values of type %2")
- << Value(Data->FromType, From) << Data->FromType << Data->ToType;
+ << Value(*FromType, From) << *FromType << *ToType;
}
-void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
- ValueHandle From) {
+void __ubsan::__ubsan_handle_float_cast_overflow(void *Data, ValueHandle From) {
GET_REPORT_OPTIONS(false);
handleFloatCastOverflow(Data, From, Opts);
}
-void
-__ubsan::__ubsan_handle_float_cast_overflow_abort(FloatCastOverflowData *Data,
- ValueHandle From) {
+void __ubsan::__ubsan_handle_float_cast_overflow_abort(void *Data,
+ ValueHandle From) {
GET_REPORT_OPTIONS(true);
handleFloatCastOverflow(Data, From, Opts);
Die();
diff --git a/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h
index 87149f259..25093d432 100644
--- a/lib/ubsan/ubsan_handlers.h
+++ b/lib/ubsan/ubsan_handlers.h
@@ -97,14 +97,22 @@ struct VLABoundData {
/// \brief Handle a VLA with a non-positive bound.
RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)
+// Keeping this around for binary compatibility with (sanitized) programs
+// compiled with older compilers.
struct FloatCastOverflowData {
- // FIXME: SourceLocation Loc;
const TypeDescriptor &FromType;
const TypeDescriptor &ToType;
};
-/// \brief Handle overflow in a conversion to or from a floating-point type.
-RECOVERABLE(float_cast_overflow, FloatCastOverflowData *Data, ValueHandle From)
+struct FloatCastOverflowDataV2 {
+ SourceLocation Loc;
+ const TypeDescriptor &FromType;
+ const TypeDescriptor &ToType;
+};
+
+/// Handle overflow in a conversion to or from a floating-point type.
+/// void *Data is one of FloatCastOverflowData* or FloatCastOverflowDataV2*
+RECOVERABLE(float_cast_overflow, void *Data, ValueHandle From)
struct InvalidValueData {
SourceLocation Loc;