[compiler-rt] [mlir] [libcxx] [llvm] [clang] [asan] Enable StackSafetyAnalysis by default (PR #77210)

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 19 11:10:34 PST 2024


MaskRay wrote:

@uweigand 

Thanks for the analysis. `bot = alloca(i);` is a dynamic alloca that cannot be optimized out.
It triggers `FunctionStackPoisoner::createDynamicAllocasInitStorage`, which creates an alloca of 32-byte alignment.
In x86-64, aarch64, riscv, and others, the alloca translates to a `StackObject` of 32-byte alignment.
When `char array[len]` is not instrumented (due to StackSafetyAnalysis), only 16-byte alignment is guaranteed, but it ends up being 32-byte aligned due to the frame layout.

On s390x, it seems that all `StackObject`s are just 4-byte or 8-byte aligned. Therefore, the first `char array[len]`, if not instrumented, is not 32-byte aligned.

I think the following patch should fix the failure on s390x.
Note: `char array[i]` in the loop is not instrumented due to the `isAllocaPromotable(&AI)` optimization (which I want to get rid of in #77221).
Whether `char array[i]` gets instrumented or not does not make the result different, but instrumenting it may make the test more intesting.
(Without the VLA `alloca(i)` returns a different address in each iteration).

```diff
--- i/compiler-rt/test/asan/TestCases/alloca_loop_unpoisoning.cpp
+++ w/compiler-rt/test/asan/TestCases/alloca_loop_unpoisoning.cpp
@@ -4,3 +4,2 @@
 // REQUIRES: stable-runtime
-// UNSUPPORTED: target=s390{{.*}}

@@ -28,2 +27,3 @@ __attribute__((noinline)) void foo(int len) {
   char array[len];
+  if (len) array[0] = 0;
   assert(!(reinterpret_cast<uintptr_t>(array) & 31L));
@@ -32,2 +32,3 @@ __attribute__((noinline)) void foo(int len) {
     char array[i];
+    if (i) array[0] = 0;
     bot = alloca(i);
```


https://github.com/llvm/llvm-project/pull/77210


More information about the cfe-commits mailing list