Index: compiler-rt/trunk/lib/asan/asan_rtl.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_rtl.cc +++ compiler-rt/trunk/lib/asan/asan_rtl.cc @@ -459,7 +459,10 @@ if (CAN_SANITIZE_LEAKS) { __lsan::InitCommonLsan(); if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { - Atexit(__lsan::DoLeakCheck); + if (flags()->halt_on_error) + Atexit(__lsan::DoLeakCheck); + else + Atexit(__lsan::DoRecoverableLeakCheckVoid); } } Index: compiler-rt/trunk/lib/lsan/lsan_common.h =================================================================== --- compiler-rt/trunk/lib/lsan/lsan_common.h +++ compiler-rt/trunk/lib/lsan/lsan_common.h @@ -145,6 +145,7 @@ // Functions called from the parent tool. void InitCommonLsan(); void DoLeakCheck(); +void DoRecoverableLeakCheckVoid(); void DisableCounterUnderflow(); bool DisabledInThisThread(); Index: compiler-rt/trunk/lib/lsan/lsan_common.cc =================================================================== --- compiler-rt/trunk/lib/lsan/lsan_common.cc +++ compiler-rt/trunk/lib/lsan/lsan_common.cc @@ -593,6 +593,8 @@ return have_leaks ? 1 : 0; } +void DoRecoverableLeakCheckVoid() { DoRecoverableLeakCheck(); } + static Suppression *GetSuppressionForAddr(uptr addr) { Suppression *s = nullptr; @@ -755,6 +757,7 @@ namespace __lsan { void InitCommonLsan() { } void DoLeakCheck() { } +void DoRecoverableLeakCheckVoid() { } void DisableInThisThread() { } void EnableInThisThread() { } } Index: compiler-rt/trunk/test/asan/TestCases/recoverable-lsan.cc =================================================================== --- compiler-rt/trunk/test/asan/TestCases/recoverable-lsan.cc +++ compiler-rt/trunk/test/asan/TestCases/recoverable-lsan.cc @@ -0,0 +1,21 @@ +// Ensure that output is the same but exit code depends on halt_on_error value +// RUN: %clangxx_asan %s -o %t +// RUN: %env_asan_opts="halt_on_error=0" %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts="halt_on_error=1" not %run %t 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s + +#include + +int f() { + volatile int *a = (int *)malloc(20); + a[0] = 1; + return a[0]; +} + +int main() { + f(); + f(); +} + +// CHECK: LeakSanitizer: detected memory leaks +// CHECK: SUMMARY: AddressSanitizer: 20 byte(s) leaked