forked from OSchip/llvm-project
[UBSan] Reduce the number of getCallerLocation() calls.
getCallerLocation() is expensive as it issues a call to symbolizer. (In fact, this function has a memory leak at the moment, but this will be fixed in the nearest future). We should only call it if we're actually going to print an error report, in particular, once for every reported source location. __ubsan_handle_type_mismatch: call getCallerLocation() only if provided source location is invalid, and only if the report is not deduplicated. __ubsan_handle_float_cast_overflow: call getSourceLocation with correct CallerPC (the one in user code, not in UBSan handler). Source location for this check is not currently emitted by frontend. llvm-svn: 228732
This commit is contained in:
parent
43c0d2db50
commit
1923595b4f
|
@ -66,25 +66,24 @@ class Decorator : public SanitizerCommonDecorator {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Location __ubsan::getCallerLocation(uptr CallerLoc) {
|
Location __ubsan::getCallerLocation(uptr CallerPC) {
|
||||||
if (!CallerLoc)
|
if (!CallerPC)
|
||||||
return Location();
|
return Location();
|
||||||
|
|
||||||
uptr Loc = StackTrace::GetPreviousInstructionPc(CallerLoc);
|
return getFunctionLocation(StackTrace::GetPreviousInstructionPc(CallerPC), 0);
|
||||||
return getFunctionLocation(Loc, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Location __ubsan::getFunctionLocation(uptr Loc, const char **FName) {
|
Location __ubsan::getFunctionLocation(uptr PC, const char **FName) {
|
||||||
if (!Loc)
|
if (!PC)
|
||||||
return Location();
|
return Location();
|
||||||
InitIfNecessary();
|
InitIfNecessary();
|
||||||
|
|
||||||
SymbolizedStack *Frames = Symbolizer::GetOrInit()->SymbolizePC(Loc);
|
SymbolizedStack *Frames = Symbolizer::GetOrInit()->SymbolizePC(PC);
|
||||||
const AddressInfo &Info = Frames->info;
|
const AddressInfo &Info = Frames->info;
|
||||||
|
|
||||||
if (!Info.module) {
|
if (!Info.module) {
|
||||||
Frames->ClearAll();
|
Frames->ClearAll();
|
||||||
return Location(Loc);
|
return Location(PC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FName && Info.function)
|
if (FName && Info.function)
|
||||||
|
|
|
@ -80,13 +80,13 @@ public:
|
||||||
|
|
||||||
/// Try to obtain a location for the caller. This might fail, and produce either
|
/// Try to obtain a location for the caller. This might fail, and produce either
|
||||||
/// an invalid location or a module location for the caller.
|
/// an invalid location or a module location for the caller.
|
||||||
Location getCallerLocation(uptr CallerLoc = GET_CALLER_PC());
|
Location getCallerLocation(uptr CallerPC);
|
||||||
|
|
||||||
/// Try to obtain a location for the given function pointer. This might fail,
|
/// Try to obtain a location for the given function pointer. This might fail,
|
||||||
/// and produce either an invalid location or a module location for the caller.
|
/// and produce either an invalid location or a module location for the caller.
|
||||||
/// If FName is non-null and the name of the function is known, set *FName to
|
/// If FName is non-null and the name of the function is known, set *FName to
|
||||||
/// the function name, otherwise *FName is unchanged.
|
/// the function name, otherwise *FName is unchanged.
|
||||||
Location getFunctionLocation(uptr Loc, const char **FName);
|
Location getFunctionLocation(uptr PC, const char **FName);
|
||||||
|
|
||||||
/// A diagnostic severity level.
|
/// A diagnostic severity level.
|
||||||
enum DiagLevel {
|
enum DiagLevel {
|
||||||
|
|
|
@ -37,14 +37,14 @@ const char *TypeCheckKinds[] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
|
static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
|
||||||
Location FallbackLoc, ReportOptions Opts) {
|
ReportOptions Opts) {
|
||||||
Location Loc = Data->Loc.acquire();
|
Location Loc = Data->Loc.acquire();
|
||||||
// Use the SourceLocation from Data to track deduplication, even if 'invalid'
|
// Use the SourceLocation from Data to track deduplication, even if 'invalid'
|
||||||
if (ignoreReport(Loc.getSourceLocation(), Opts))
|
if (ignoreReport(Loc.getSourceLocation(), Opts))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Data->Loc.isInvalid())
|
if (Data->Loc.isInvalid())
|
||||||
Loc = FallbackLoc;
|
Loc = getCallerLocation(Opts.pc);
|
||||||
|
|
||||||
ScopedReport R(Opts, Loc);
|
ScopedReport R(Opts, Loc);
|
||||||
|
|
||||||
|
@ -67,12 +67,12 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
|
||||||
void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,
|
void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,
|
||||||
ValueHandle Pointer) {
|
ValueHandle Pointer) {
|
||||||
GET_REPORT_OPTIONS(false);
|
GET_REPORT_OPTIONS(false);
|
||||||
handleTypeMismatchImpl(Data, Pointer, getCallerLocation(), Opts);
|
handleTypeMismatchImpl(Data, Pointer, Opts);
|
||||||
}
|
}
|
||||||
void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,
|
void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,
|
||||||
ValueHandle Pointer) {
|
ValueHandle Pointer) {
|
||||||
GET_REPORT_OPTIONS(true);
|
GET_REPORT_OPTIONS(true);
|
||||||
handleTypeMismatchImpl(Data, Pointer, getCallerLocation(), Opts);
|
handleTypeMismatchImpl(Data, Pointer, Opts);
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
|
||||||
static void handleFloatCastOverflow(FloatCastOverflowData *Data,
|
static void handleFloatCastOverflow(FloatCastOverflowData *Data,
|
||||||
ValueHandle From, ReportOptions Opts) {
|
ValueHandle From, ReportOptions Opts) {
|
||||||
// TODO: Add deduplication once a SourceLocation is generated for this check.
|
// TODO: Add deduplication once a SourceLocation is generated for this check.
|
||||||
Location Loc = getCallerLocation();
|
Location Loc = getCallerLocation(Opts.pc);
|
||||||
ScopedReport R(Opts, Loc);
|
ScopedReport R(Opts, Loc);
|
||||||
|
|
||||||
Diag(Loc, DL_Error,
|
Diag(Loc, DL_Error,
|
||||||
|
|
Loading…
Reference in New Issue