[clang] [WIP][clang]: Implement a conditional lifetimebound_if builtin. (PR #125520)

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 4 05:01:19 PST 2025


ilya-biryukov wrote:

In addition to the concerns raised above, I also wanted to highlight that as soon as we have the ability to inspect attributes (and I agree with @higher-performance that we want it to make this useful for cases like `emplace_back`) at compile time, we get into a slippery slope of allowing template instantiations based on that, i.e. leaking attributes into ABI, which seems to go against the design principles of those attributes.

And since lifetimebound analysis is best-effort and does not provide actual safety guarantees (has both false positives and false negatives), it'd be nice to ensure the design does not allow it to slip past the `lifetimebound` attributes themselves.

Summing up, I would actually propose to have a slightly weird version of the "getters" that would only be usable in those `lifetimebound` attrs themselves (combining suggestion from @higher-performance and this PR):

```cpp
// Terribly name for the attribute, could be better.
template<class... Args>
reference emplace_back(Args&&... args [[clang::lifetimebound_if_lifetimebound(*new T(std::forward<Args>(args)...)))]]);
```
if we want more conditions, we could additionally allow some conditional expressions:
```cpp
// Slightly confusing syntax, could definitely be better.
template<class... Args>
reference emplace_back(Args&&... args [[clang::lifetimebound_if_lifetimebound_and(*new T(std::forward<Args>(args)...)), std::is_reference_type_v(args))]]);
```

More generally, my call is to figure out how to not leak the results of this analysis to the outside world to avoid the Hyrum's law effect where we cannot change it.

I am also unsure about the granularity here. For `emplace_back`, what we probably want is to have `lifetimebound` only on parameters that are marked as lifetimebound in the constructor. However, in the proposed approach we end up marking additional parameters too. Would that result in more false positives?

See https://gcc.godbolt.org/z/boPeheMsK 
```cpp
#include <memory>

struct X {
  X(const int &a, [[clang::lifetimebound]] const int&b);
};

void foo() {
  int a = 1;
  X x(a, 2); // warning.
  X y(1, a); // no warning.

  // make_unique would have both warnings, right?
  // similarly, for emplace_back.
  auto px = std::make_unique<X>(a, 2);
  auto py = std::make_unique<X>(1, a);
}
```

Is there a way to avoid it?

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


More information about the cfe-commits mailing list