Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -450,17 +450,23 @@ AU.addRequired(); } uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { + uint64_t ArraySize = 1; + if (AI->isArrayAllocation()) { + ConstantInt *CI = dyn_cast(AI->getArraySize()); + assert(CI && "non-constant array size"); + ArraySize = CI->getZExtValue(); + } Type *Ty = AI->getAllocatedType(); uint64_t SizeInBytes = AI->getModule()->getDataLayout().getTypeAllocSize(Ty); - return SizeInBytes; + return SizeInBytes * ArraySize; } /// Check if we want (and can) handle this alloca. bool isInterestingAlloca(AllocaInst &AI); // Check if we have dynamic alloca. bool isDynamicAlloca(AllocaInst &AI) const { - return AI.isArrayAllocation() || !AI.isStaticAlloca(); + return !AI.isStaticAlloca(); } /// If it is an interesting memory access, return the PointerOperand @@ -897,6 +903,7 @@ return PreviouslySeenAllocaInfo->getSecond(); bool IsInteresting = + isDynamicAlloca(AI) || (AI.getAllocatedType()->isSized() && // alloca() may be called with 0 size, ignore it. getAllocaSizeInBytes(&AI) > 0 && Index: projects/compiler-rt/test/asan/TestCases/alloca_constant_size.cc =================================================================== --- projects/compiler-rt/test/asan/TestCases/alloca_constant_size.cc +++ projects/compiler-rt/test/asan/TestCases/alloca_constant_size.cc @@ -0,0 +1,30 @@ +// Regression test for https://github.com/google/sanitizers/issues/691 + +// RUN: %clangxx_asan -O0 %s -o %t -fstack-protector +// RUN: %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +void f1() { + char *dynamic_buffer = (char *)alloca(200); + fprintf(stderr, "dynamic_buffer = %p\n", dynamic_buffer); + memset(dynamic_buffer, 'y', 200); + return; +} + +void f2() { + char buf[1024]; + memset(buf, 'x', 1024); +} + +int main(int argc, const char *argv[]) { + f1(); + f2(); + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK-NOT: ERROR: AddressSanitizer +// CHECK: Done. Index: projects/compiler-rt/test/asan/TestCases/alloca_constant_size2.cc =================================================================== --- projects/compiler-rt/test/asan/TestCases/alloca_constant_size2.cc +++ projects/compiler-rt/test/asan/TestCases/alloca_constant_size2.cc @@ -0,0 +1,32 @@ +// Regression test for https://github.com/google/sanitizers/issues/691 + +// RUN: %clangxx_asan -O0 %s -o %t -fstack-protector +// RUN: %run %t 2>&1 | FileCheck %s + +#include +#include +#include + +static const int kDynamicArraySize = 200; + +void f1() { + char dynamic_buffer[kDynamicArraySize]; + fprintf(stderr, "dynamic_buffer = %p\n", dynamic_buffer); + memset(dynamic_buffer, 'y', kDynamicArraySize); + return; +} + +void f2() { + char buf[1024]; + memset(buf, 'x', 1024); +} + +int main(int argc, const char *argv[]) { + f1(); + f2(); + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK-NOT: ERROR: AddressSanitizer +// CHECK: Done.