Camsyn 59b26abbbe
[TSan, SanitizerBinaryMetadata] Analyze the capture status for alloca rather than arbitrary Addr (#132756)
This PR is based on my last PR #132752 (the first commit of this PR),
but addressing a different issue.

This commit addresses the limitation in `PointerMayBeCaptured` analysis
when dealing with derived pointers (e.g. arr+1) as described in issue
#132739.

The current implementation of `PointerMayBeCaptured` may miss captures
of the underlying `alloca` when analyzing derived pointers, leading to
some FNs in TSan, as follows:
```cpp
void *Thread(void *a) {
  ((int*)a)[1] = 43;
  return 0;
}

int main() {
  int Arr[2] = {41, 42};
  pthread_t t;
  pthread_create(&t, 0, Thread, &Arr[0]);
  // Missed instrumentation here due to the FN of PointerMayBeCaptured
  Arr[1] = 43;
  barrier_wait(&barrier);
  pthread_join(t, 0);
}
```
Refer to this [godbolt page](https://godbolt.org/z/n67GrxdcE) to get the
compilation result of TSan.

Even when `PointerMayBeCaptured` working correctly, it should backtrack
to the original `alloca` firstly during analysis, causing redundancy to
the outer's `findAllocaForValue`.
```cpp
    const AllocaInst *AI = findAllocaForValue(Addr);
    // Instead of Addr, we should check whether its base pointer is captured.
    if (AI && !PointerMayBeCaptured(Addr, true)) ...
```

Key changes:
Directly analyze the capture status of the underlying `alloca` instead
of derived pointers to ensure accurate capture detection
```cpp
    const AllocaInst *AI = findAllocaForValue(Addr);
    // Instead of Addr, we should check whether its base pointer is captured.
    if (AI && !PointerMayBeCaptured(AI, true)) ...
```
2025-04-24 10:48:07 +02:00

22 lines
458 B
C++

// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
#include "test.h"
void *Thread(void *a) {
barrier_wait(&barrier);
((int *)a)[1] = 43;
return 0;
}
int main() {
barrier_init(&barrier, 2);
int Arr[2] = {41, 42};
pthread_t t;
pthread_create(&t, 0, Thread, &Arr[0]);
Arr[1] = 43;
barrier_wait(&barrier);
pthread_join(t, 0);
}
// CHECK: WARNING: ThreadSanitizer: data race
// CHECK: Location is stack of main thread.