hokein wrote: Another thought for supporting the `emplace_back(Args...)` case (for STL only).
The underlying implementation of the `emplace_back` relies on `std::allocator_traits::construct(Alloc& a, T* p, Args&&... args)`, so we could use the `lifetime_capture_by` annotation in the instantiated function (this annotation can be relatively easy to infer in clang). For example, consider an instantiated template (note that the function parameter should be an non-const rvalue reference): ```cpp construct(std::string_view* p, std::string&& arg [[clang::lifetime_capture_by(p)]]); ``` Here, we annotate `arg` with `lifetime_capture_by(p)`, which should allow us to detect cases like: ```cpp construct(&view, std::string()); // Detects dangling pointer ``` However, this approach doesn’t work for `emplace_back`, because in that case, we only see perfect forwarding in the function arguments (`construct(std::__to_address(__tx.__pos_), std::forward<_Args>(__args)...);`) ### Potential Extension: We could consider extending the analysis scope for non-const rvalue references. Specifically if a non-const rvalue reference parameter is annotated, we could always emit a warning when this function is being called. Example: ```cpp void add(std::vector<std::string_view>& container, std::string&& s [[clang::lifetime_capture_by]]); void test() { std::vector<std::string_view> abc; add(abc, std::string()); // Case 1: Warning, point to a dead object std::string b; add(abc, std::move(b)); // Case 2: point to a moved-from object add(abc, b); // invalid c++ code, cannot bind a lvalue to rvalue reference } ``` For non-const rvalue reference function parameters, there are only two legal options to pass the argument: 1. A temporary object. 2. A non-const object explicitly marked with `std::move()`. - **Case 1)** is a clear use-after-free issue, which is already detected by the current implementation. - **Case 2)** is a bit subtle. The moved-from object is still alive but in a valid-but-unspecified state. While it’s technically possible to use the object after a `std::move()`, the general programming guideline is to avoid doing so, as it could lead to potential use-after-move issues (we have a use-after-move clang-tidy check). If we extend the analysis to warn on Case (2), we should be able to detect the `emplace_back` case. However, I’m not sure whether making the compiler stricter on this is a feasible idea. 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