Index: compiler-rt/lib/asan/asan_errors.h =================================================================== --- compiler-rt/lib/asan/asan_errors.h +++ compiler-rt/lib/asan/asan_errors.h @@ -296,6 +296,24 @@ void Print(); }; +struct ErrorUseAfterScope : ErrorBase { + uptr pc, bp, sp; + const char *variable_name; + uptr variable_size; + // VS2013 doesn't implement unrestricted unions, so we need a trivial default + // constructor + ErrorUseAfterScope() = default; + ErrorUseAfterScope(u32 tid, uptr pc_, uptr bp_, uptr sp_, + const char *variable_name_, uptr variable_size_) + : ErrorBase(tid), + pc(pc_), + bp(bp_), + sp(sp_), + variable_name(variable_name_), + variable_size(variable_size_) {} + void Print(); +}; + struct ErrorGeneric : ErrorBase { AddressDescription addr_description; uptr pc, bp, sp; @@ -326,6 +344,7 @@ macro(BadParamsToAnnotateContiguousContainer) \ macro(ODRViolation) \ macro(InvalidPointerPair) \ + macro(UseAfterScope) \ macro(Generic) // clang-format on Index: compiler-rt/lib/asan/asan_errors.cc =================================================================== --- compiler-rt/lib/asan/asan_errors.cc +++ compiler-rt/lib/asan/asan_errors.cc @@ -281,6 +281,27 @@ ReportErrorSummary(bug_type, &stack); } +void ErrorUseAfterScope::Print() { + const char *bug_type = "stack-use-after-scope"; + Decorator d; + Printf("%s", d.Warning()); + + Report("ERROR: AddressSanitizer: stack-use-after-scope at pc %p bp %p sp %p\n", + variable_name, variable_size, pc, bp, sp); + Printf("%s", d.EndWarning()); + scariness.Print(); + + char tname[128]; + Printf("ACCESS of size %zu for variable '%s' thread T%d%s%s\n", + variable_size, variable_name, tid, + ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.EndAccess()); + + GET_STACK_TRACE_FATAL(pc, bp); + stack.Print(); + ReportErrorSummary(bug_type, &stack); +} + + static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) { return s[-1] > 127 && s[1] > 127; } Index: compiler-rt/lib/asan/asan_report.h =================================================================== --- compiler-rt/lib/asan/asan_report.h +++ compiler-rt/lib/asan/asan_report.h @@ -70,6 +70,9 @@ void ReportODRViolation(const __asan_global *g1, u32 stack_id1, const __asan_global *g2, u32 stack_id2); +void ReportUseAfterScope(const char *variable_name, uptr variable_size, + bool fatal); + // Mac-specific errors and warnings. void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name, Index: compiler-rt/lib/asan/asan_report.cc =================================================================== --- compiler-rt/lib/asan/asan_report.cc +++ compiler-rt/lib/asan/asan_report.cc @@ -355,6 +355,16 @@ return ReportInvalidPointerPair(pc, bp, sp, a1, a2); } } +// ----------------------- ReportUseAfterScope ----------- {{{1 +void ReportUseAfterScope(const char *variable_name, uptr variable_size, + bool fatal) { + ScopedInErrorReport in_report (fatal); + GET_CALLER_PC_BP_SP; + ErrorUseAfterScope error(GetCurrentTidOrInvalid(), pc, bp, sp, variable_name, + variable_size); + in_report.ReportError(error); +} + // ----------------------- Mac-specific reports ----------------- {{{1 void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name, Index: compiler-rt/lib/asan/asan_rtl.cc =================================================================== --- compiler-rt/lib/asan/asan_rtl.cc +++ compiler-rt/lib/asan/asan_rtl.cc @@ -255,6 +255,22 @@ } } +#include + +extern "C" +NOINLINE INTERFACE_ATTRIBUTE +void __asan_report_use_after_scope(const char *variable_name, + uptr variable_size) { + ReportUseAfterScope(variable_name, variable_size, true); +} + +extern "C" +NOINLINE INTERFACE_ATTRIBUTE +void __asan_report_use_after_scope_noabort(const char *variable_name, + uptr variable_size) { + ReportUseAfterScope(variable_name, variable_size, false); +} + // Force the linker to keep the symbols for various ASan interface functions. // We want to keep those in the executable in order to let the instrumented // dynamic libraries access the symbol even if it is not used by the executable