[compiler-rt] r198932 - [lsan] handle 'new T[0]' where T is a type with DTOR; fixes https://code.google.com/p/address-sanitizer/issues/detail?id=257
Kostya Serebryany
kcc at google.com
Fri Jan 10 02:48:01 PST 2014
Author: kcc
Date: Fri Jan 10 04:48:01 2014
New Revision: 198932
URL: http://llvm.org/viewvc/llvm-project?rev=198932&view=rev
Log:
[lsan] handle 'new T[0]' where T is a type with DTOR; fixes https://code.google.com/p/address-sanitizer/issues/detail?id=257
Added:
compiler-rt/trunk/lib/lsan/lit_tests/TestCases/new_array_with_dtor_0.cc
Modified:
compiler-rt/trunk/lib/asan/asan_allocator2.cc
compiler-rt/trunk/lib/lsan/lsan_allocator.cc
compiler-rt/trunk/lib/lsan/lsan_common.h
Modified: compiler-rt/trunk/lib/asan/asan_allocator2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator2.cc?rev=198932&r1=198931&r2=198932&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Fri Jan 10 04:48:01 2014
@@ -710,8 +710,12 @@ uptr PointsIntoChunk(void* p) {
__asan::AsanChunk *m = __asan::GetAsanChunkByAddrFastLocked(addr);
if (!m) return 0;
uptr chunk = m->Beg();
- if ((m->chunk_state == __asan::CHUNK_ALLOCATED) &&
- m->AddrIsInside(addr, /*locked_version=*/true))
+ if (m->chunk_state != __asan::CHUNK_ALLOCATED)
+ return 0;
+ if (m->AddrIsInside(addr, /*locked_version=*/true))
+ return chunk;
+ if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),
+ addr))
return chunk;
return 0;
}
Added: compiler-rt/trunk/lib/lsan/lit_tests/TestCases/new_array_with_dtor_0.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lit_tests/TestCases/new_array_with_dtor_0.cc?rev=198932&view=auto
==============================================================================
--- compiler-rt/trunk/lib/lsan/lit_tests/TestCases/new_array_with_dtor_0.cc (added)
+++ compiler-rt/trunk/lib/lsan/lit_tests/TestCases/new_array_with_dtor_0.cc Fri Jan 10 04:48:01 2014
@@ -0,0 +1,19 @@
+// Regression test:
+// https://code.google.com/p/address-sanitizer/issues/detail?id=257
+// RUN: %clangxx_lsan %s -o %t && %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+
+struct T {
+ ~T() { printf("~T\n"); }
+};
+
+T *t;
+
+int main(int argc, char **argv) {
+ t = new T[argc - 1];
+ printf("OK\n");
+}
+
+// CHECK: OK
+
Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.cc?rev=198932&r1=198931&r2=198932&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.cc Fri Jan 10 04:48:01 2014
@@ -143,7 +143,11 @@ uptr PointsIntoChunk(void* p) {
if (addr < chunk) return 0;
ChunkMetadata *m = Metadata(reinterpret_cast<void *>(chunk));
CHECK(m);
- if (m->allocated && addr < chunk + m->requested_size)
+ if (!m->allocated)
+ return 0;
+ if (addr < chunk + m->requested_size)
+ return chunk;
+ if (IsSpecialCaseOfOperatorNew0(chunk, m->requested_size, addr))
return chunk;
return 0;
}
Modified: compiler-rt/trunk/lib/lsan/lsan_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_common.h?rev=198932&r1=198931&r2=198932&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_common.h (original)
+++ compiler-rt/trunk/lib/lsan/lsan_common.h Fri Jan 10 04:48:01 2014
@@ -139,6 +139,15 @@ void InitCommonLsan();
void DoLeakCheck();
bool DisabledInThisThread();
+// Special case for "new T[0]" where T is a type with DTOR.
+// new T[0] will allocate one word for the array size (0) and store a pointer
+// to the end of allocated chunk.
+inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg, uptr chunk_size,
+ uptr addr) {
+ return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr &&
+ *reinterpret_cast<uptr *>(chunk_beg) == 0;
+}
+
// The following must be implemented in the parent tool.
void ForEachChunk(ForEachChunkCallback callback, void *arg);
More information about the llvm-commits
mailing list