summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-09-19 18:33:45 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-09-19 18:33:45 +0000
commita82d43abfe5ac2c3067bbd71a17bb94cd5d4ba1f (patch)
treee98c5bf0b48130caef75e09a8f8b2c72aefe235b
parent2bc599a96d1e7cb308b470fa18f6df45e7561a50 (diff)
[UBSan] Optionally report summary in UBSan error reports.
By default summary is not printed if UBSan is run in a standalone mode, but is printed if it's combined with another sanitizer (like ASan). git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@218135 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_common.h2
-rw-r--r--lib/ubsan/ubsan_diag.cc20
-rw-r--r--lib/ubsan/ubsan_diag.h3
-rw-r--r--lib/ubsan/ubsan_handlers.cc35
-rw-r--r--lib/ubsan/ubsan_handlers_cxx.cc2
-rw-r--r--test/ubsan/TestCases/Integer/summary.cpp10
-rw-r--r--test/ubsan/lit.common.cfg2
7 files changed, 53 insertions, 21 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index c85264aef..cf41b5a9a 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -250,7 +250,7 @@ const int kMaxSummaryLength = 1024;
// and pass it to __sanitizer_report_error_summary.
void ReportErrorSummary(const char *error_message);
// Same as above, but construct error_message as:
-// error_type: file:line function
+// error_type file:line function
void ReportErrorSummary(const char *error_type, const char *file,
int line, const char *function);
void ReportErrorSummary(const char *error_type, StackTrace *trace);
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index ea2fa9b44..33babaf3d 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -38,6 +38,22 @@ static void MaybePrintStackTrace(uptr pc, uptr bp) {
stack.Print();
}
+static void MaybeReportErrorSummary(Location Loc) {
+ if (!common_flags()->print_summary)
+ return;
+ // Don't try to unwind the stack trace in UBSan summaries: just use the
+ // provided location.
+ if (Loc.isSourceLocation()) {
+ SourceLocation SLoc = Loc.getSourceLocation();
+ if (!SLoc.isInvalid()) {
+ ReportErrorSummary("runtime-error", SLoc.getFilename(), SLoc.getLine(),
+ "");
+ return;
+ }
+ }
+ ReportErrorSummary("runtime-error");
+}
+
namespace {
class Decorator : public SanitizerCommonDecorator {
public:
@@ -315,13 +331,15 @@ Diag::~Diag() {
NumRanges, Args);
}
-ScopedReport::ScopedReport(ReportOptions Opts) : Opts(Opts) {
+ScopedReport::ScopedReport(ReportOptions Opts, Location SummaryLoc)
+ : Opts(Opts), SummaryLoc(SummaryLoc) {
InitIfNecessary();
CommonSanitizerReportMutex.Lock();
}
ScopedReport::~ScopedReport() {
MaybePrintStackTrace(Opts.pc, Opts.bp);
+ MaybeReportErrorSummary(SummaryLoc);
CommonSanitizerReportMutex.Unlock();
if (Opts.DieAfterReport || flags()->halt_on_error)
Die();
diff --git a/lib/ubsan/ubsan_diag.h b/lib/ubsan/ubsan_diag.h
index b2fe735a2..296ec0d3f 100644
--- a/lib/ubsan/ubsan_diag.h
+++ b/lib/ubsan/ubsan_diag.h
@@ -223,9 +223,10 @@ struct ReportOptions {
/// different sanitizers won't be mixed.
class ScopedReport {
ReportOptions Opts;
+ Location SummaryLoc;
public:
- ScopedReport(ReportOptions Opts);
+ ScopedReport(ReportOptions Opts, Location SummaryLoc);
~ScopedReport();
};
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index f6d1a0eeb..f8365a7d2 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -43,11 +43,11 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
if (ignoreReport(Loc.getSourceLocation(), Opts))
return;
- ScopedReport R(Opts);
-
if (Data->Loc.isInvalid())
Loc = FallbackLoc;
+ ScopedReport R(Opts, Loc);
+
if (!Pointer)
Diag(Loc, DL_Error, "%0 null pointer of type %1")
<< TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
@@ -85,7 +85,7 @@ static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error, "%0 integer overflow: "
"%1 %2 %3 cannot be represented in type %4")
@@ -114,7 +114,7 @@ static void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
if (Data->Type.isSignedIntegerTy())
Diag(Loc, DL_Error,
@@ -145,7 +145,7 @@ static void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Value LHSVal(Data->Type, LHS);
Value RHSVal(Data->Type, RHS);
@@ -177,7 +177,7 @@ static void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Value LHSVal(Data->LHSType, LHS);
Value RHSVal(Data->RHSType, RHS);
@@ -216,7 +216,7 @@ static void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Value IndexVal(Data->IndexType, Index);
Diag(Loc, DL_Error, "index %0 out of bounds for type %1")
@@ -237,7 +237,7 @@ void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,
static void handleBuiltinUnreachableImpl(UnreachableData *Data,
ReportOptions Opts) {
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Data->Loc);
Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call");
}
@@ -248,7 +248,7 @@ void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {
}
static void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) {
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Data->Loc);
Diag(Data->Loc, DL_Error,
"execution reached the end of a value-returning function "
"without returning a value");
@@ -266,7 +266,7 @@ static void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error, "variable length array bound evaluates to "
"non-positive value %0")
@@ -288,11 +288,12 @@ void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
static void handleFloatCastOverflow(FloatCastOverflowData *Data,
ValueHandle From, ReportOptions Opts) {
// TODO: Add deduplication once a SourceLocation is generated for this check.
- ScopedReport R(Opts);
+ Location Loc = getCallerLocation();
+ ScopedReport R(Opts, Loc);
- Diag(getCallerLocation(), DL_Error,
+ 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(Data->FromType, From) << Data->FromType << Data->ToType;
}
void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
@@ -314,7 +315,7 @@ static void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val,
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error,
"load of value %0, which is not a valid value for type %1")
@@ -340,7 +341,7 @@ static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
Location Loc = getFunctionLocation(Function, &FName);
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Data->Loc, DL_Error,
"call to function %0 through pointer to incorrect function type %1")
@@ -367,7 +368,7 @@ static void handleNonNullReturn(NonNullReturnData *Data, ReportOptions Opts) {
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error, "null pointer returned from function declared to never "
"return null");
@@ -391,7 +392,7 @@ static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts) {
if (ignoreReport(Loc, Opts))
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error, "null pointer passed as argument %0, which is declared to "
"never be null") << Data->ArgIndex;
diff --git a/lib/ubsan/ubsan_handlers_cxx.cc b/lib/ubsan/ubsan_handlers_cxx.cc
index fa244c85d..5704c1e63 100644
--- a/lib/ubsan/ubsan_handlers_cxx.cc
+++ b/lib/ubsan/ubsan_handlers_cxx.cc
@@ -44,7 +44,7 @@ static void HandleDynamicTypeCacheMiss(
if (Loc.isDisabled())
return;
- ScopedReport R(Opts);
+ ScopedReport R(Opts, Loc);
Diag(Loc, DL_Error,
"%0 address %1 which does not point to an object of type %2")
diff --git a/test/ubsan/TestCases/Integer/summary.cpp b/test/ubsan/TestCases/Integer/summary.cpp
new file mode 100644
index 000000000..d6fecd2ab
--- /dev/null
+++ b/test/ubsan/TestCases/Integer/summary.cpp
@@ -0,0 +1,10 @@
+// RUN: %clangxx -fsanitize=integer %s -o %t && %t 2>&1 | FileCheck %s
+// REQUIRES: ubsan-asan
+
+#include <stdint.h>
+
+int main() {
+ (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
+ // CHECK: SUMMARY: AddressSanitizer: runtime-error {{.*}}summary.cpp:[[@LINE-1]]
+ return 0;
+}
diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg
index 4e3e377f0..b91b4bf5a 100644
--- a/test/ubsan/lit.common.cfg
+++ b/test/ubsan/lit.common.cfg
@@ -18,9 +18,11 @@ config.test_source_root = os.path.dirname(__file__)
ubsan_lit_test_mode = get_required_attr(config, 'ubsan_lit_test_mode')
if ubsan_lit_test_mode == "Standalone":
config.name = 'UndefinedBehaviorSanitizer-Standalone'
+ config.available_features.add("ubsan-standalone")
clang_ubsan_cflags = []
elif ubsan_lit_test_mode == "AddressSanitizer":
config.name = 'UndefinedBehaviorSanitizer-AddressSanitizer'
+ config.available_features.add("ubsan-asan")
clang_ubsan_cflags = ["-fsanitize=address"]
config.environment['ASAN_OPTIONS'] = 'detect_leaks=0'
else: