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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits