[clang] [WIP][clang]: Implement a conditional lifetimebound_if builtin. (PR #125520)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 4 09:58:19 PST 2025
higher-performance wrote:
> There are other ways to achieve that and there are attributes that may change behavior of the program and its meaning, so maybe some folks feel it is acceptable. I feel this is probably a bad idea and we should stick to the principle that attributes like lifetimebound can be safety removed without changing runtime semantics of the program.
Ahh I see what you mean. Yeah, as you mentioned I think that cat is already out of the bag with attributes like `[[no_unique_address]]`/`[[clang::using_if_exists]]`/`[[clang::trivial_abi]]`/`[[clang::enable_if(...)]]`/... so I'm not as worried about it. In fact I think even `[[clang::diagnose_if(...)]]` can cause template instantiations that change program behavior.
That said, we can avoid most of this problem quite easily (...in principle; perhaps not simple in implementation) I think: by preventing the query built-in from being usable anywhere outside of lifetime analysis.
> `noexcept` and lifetimebound are quite orthogonal, so I am a little unsure about the particular proposal as is.
Their meanings are, but their specifications seem very similar: in both cases, they are trying to say, "when diagnosing {this characteristic} of this function, do it assuming the function is equivalent to {this code}". That said -- I do agree I'm not 100% on board with using `noexcept` for this purpose either. My reason is slightly different though: the moment we have _another_ analysis to add to the picture (something other than lifetimebound), we might run into a case where we want one part of the spec for one analysis, and another for the other... and I can't think of a decent way to do that. At the same time, I'm not sure how likely that scenario is?
> However, I am also for avoiding duplication if possible. And given that the template function bodies have to be available anyway, we could maybe even utilize them (for function that don't have `noexcept`).. I am thinking about some combination of two attributes (this gets complex really quickly, as you can see, looking for better ideas):
If we could utilize the actual body, that would be perfect. However... would it be feasible to make this work for `emplace_back`? Because `emplace_back` returns `reference`, not `void`. And even the simplest of wrappers
```
template<class... Args>
reference emplace_back(Args&&... args) {
my_vector.push_back(T(std::forward<Args>()...));
return my_vector.back();
}
```
would seem to make it pretty difficult for the compiler to analyze what the lifetime relationship to the return value is.
____
Here's another idea though, combining all of the suggestions above (including @kinu's suggestion): if we forego trying to avoid code duplication, this seems like it could work:
```
template<class... Args>
reference emplace_back(Args&&... args)
[[clang::lifetimebound_like(new T(std::forward<Args>(args)...))]];
```
Thoughts?
https://github.com/llvm/llvm-project/pull/125520
More information about the cfe-commits
mailing list