[libcxx-commits] [libcxx] Add [[clang::lifetimebound]] to numerous functions in libc++ include headers (PR #112751)
Haojian Wu via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Oct 29 01:34:08 PDT 2024
hokein wrote:
Taking a closer look, it seems there's a bug in how the analyzer processes GSL pointers:
- When encountering a constructor for a `gsl::pointer`, the analyzer continues traversing the constructor argument, regardless of whether the parameter has a `lifetimebound` annotation. This aims to catch cases where a GSL pointer is constructed from a GSL owner, either directly (e.g., `FooPointer(FooOwner)`) or through a chain of GSL pointers (e.g., `FooPointer(FooPointer(FooOwner))`);
- When a temporary object is reported in the callback, the analyzer has heuristics to exclude non-owner types, aiming to avoid false positives (like `FooPointer(FooPointer())`).
In the specific case of `return foo.get();`:
- When the analyzer reports the local object `foo`, the `Path` is `[GslPointerInit, Lifetimebound]`.
- The `Path` goes through [`pathOnlyHandlesGslPointer`](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/CheckExprLifetime.cpp#L1136) and isn’t filtered out by the [[heuristics]](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/CheckExprLifetime.cpp#L1138-L1145) (because `foo` is an owner type), the analyzer treats it as the `FooPointer(FooOwner())` scenario, thus triggering a diagnostic.
One possible fix is to do the bailout if `lifetimebound` is interleaved in the GSL pointer construction. However, this will introduce a new false negative, which is probably fine (I think this case works by accident).
```cpp
FooPointer abc3() {
Container<FooOwner> foo;
return foo.get(); // return-stack-address warning on `foo`.
}
```
https://github.com/llvm/llvm-project/pull/112751
More information about the libcxx-commits
mailing list