[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