Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -450,19 +450,20 @@ 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(); - } - /// If it is an interesting memory access, return the PointerOperand /// and set IsWrite/Alignment. Otherwise return nullptr. Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, @@ -717,7 +718,7 @@ } StackAlignment = std::max(StackAlignment, AI.getAlignment()); - if (ASan.isDynamicAlloca(AI)) + if (!AI.isStaticAlloca()) DynamicAllocaVec.push_back(&AI); else AllocaVec.push_back(&AI); @@ -899,7 +900,7 @@ bool IsInteresting = (AI.getAllocatedType()->isSized() && // alloca() may be called with 0 size, ignore it. - getAllocaSizeInBytes(&AI) > 0 && + ((!AI.isStaticAlloca()) || getAllocaSizeInBytes(&AI) > 0) && // We are only interested in allocas not promotable to registers. // Promotable allocas are common under -O0. (!ClSkipPromotableAllocas || !isAllocaPromotable(&AI)) && @@ -1992,7 +1993,7 @@ assert(APC.InsBefore); assert(APC.AI); assert(ASan.isInterestingAlloca(*APC.AI)); - bool IsDynamicAlloca = ASan.isDynamicAlloca(*APC.AI); + bool IsDynamicAlloca = !(*APC.AI).isStaticAlloca(); if (!ClInstrumentAllocas && IsDynamicAlloca) continue; 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,44 @@ +// Regression test for https://github.com/google/sanitizers/issues/691 + +// RUN: %clangxx_asan -O0 %s -o %t -fstack-protector +// RUN: %run %t 1 2>&1 | FileCheck %s +// RUN: %run %t 2 2>&1 | FileCheck %s + +#include +#include +#include + +void f1_alloca() { + char *dynamic_buffer = (char *)alloca(200); + fprintf(stderr, "dynamic_buffer = %p\n", dynamic_buffer); + memset(dynamic_buffer, 'y', 200); + return; +} + +static const int kDynamicArraySize = 200; + +void f1_vla() { + 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[]) { + if (!strcmp(argv[1], "1")) { + f1_alloca(); + } else if (!strcmp(argv[1], "2")) { + f1_vla(); + } + f2(); + fprintf(stderr, "Done.\n"); + return 0; +} + +// CHECK-NOT: ERROR: AddressSanitizer +// CHECK: Done.