New clang-tidy check: finding move candidates

I’ve implemented a clang tool using clangmetatool, although I am realizing it might be a better fit inside clang-tidy and would like to get feedback on whether this tool would makes sense in clang-tidy.

The tool looks for move candidates, i.e., instances in code where the last occurrence of a variable is in some copy constructor/assignment. For example,

std::vector<int> vs = ...;

std::optional<std::vector<int>> opt_vs{vs};
// vs no longer referenced after this point

Here, the code could be improved by moving vs into opt_vs. The clang-tidy check I am proposing would identify such code and emit warnings + fixits. This tool pairs with the use-after-move check (a converse of sorts). There are a couple additional notes

  1. The tool would not suggest move trivial types (int), which would be too noisy.
  2. Containers, smart points, and algebraic types of “movable” types are considered candidates for move. E.g., vector<map<int, double>> or shared_ptr<int> etc.
  3. The tool cannot suggest moving types with non trivial destructors. This can be relaxed, potentially. What I implemented is a “mode” that is passed to the tool which allows the tool to assume types with non-trivial destructors are move candidates. Some types are hardcoded in the tool as being never-movable such as unique_lock (or shared_ptr<unique_lock> which is absurd, but possible I suppose and should never be a move candidate). This “mode” is in general not behavior preserving, but the expectation is that the end user is responsible for verifying the changes are valid.

One place to start would be a clang-tidy check which only considers always safe to move types (and containers/smart pointers/etc types of safe to move types). We could grow the tool to support the “less safe” mode if there’s interest.

Is there interest in upstreaming this check into clang-tidy? Happy to discuss requirements, or alternate approaches.

Note: I presented this tool in the form of a lightning talk at CppCon 2022 (video not up yet).