The clang-tidy static analyzer detects uses of variables after being moved.
class a_class {
std::unique_ptr<int> p_;
public:
auto p() -> auto& {return p_;}
void f() const {}
};
int main() {
auto aa = a_class{};
[[maybe_unused]] auto bb = std::move(aa);
aa.f();
}
error: Method called on moved-from object 'aa' [clang-analyzer-cplusplus.Move,-warnings-as-errors]
This great! ©.
How can I make the compiler, clang or GCC detect the same issue too? Either by activating some warning option or by some (non-standard?) attribute?
I tried using -Wmove
in clang and the [[consumed]]
attribute but they didn't help.
Perhaps I used them incorrectly.
The code is here: https://godbolt.org/z/18hr4vn7x (the lower panel is clang-tidy and the mid panel on the right is the [empty] compiler output)
Is there a chance a compiler will warn about this or it is just too costly for the compiler to check for this pattern?
CodePudding user response:
A GCC or simpler or more standard solutions are still welcome.
I found one way to do it, using attributes in clang.
- needs clang 6 or higher
- mark the class as "consumable"
- mark the method(s) "callable-when-unconsumed" (not sure how to make this the default)
class [[clang::consumable(unconsumed)]] a_class {
std::unique_ptr<int> p_;
public:
[[clang::callable_when(unconsumed)]]
void f() {}
// private: [[clang::set_typestate(consumed)]] void invalidate() {} // not needed but good to know
};
https://godbolt.org/z/45q8vzdnc
The recipe is simplified from https://awesomekling.github.io/Catching-use-after-move-bugs-with-Clang-consumed-annotations/ . I couldn't find detailed documentation on how to use the these features.
It is simplified because:
a) it seems that "clang-consumable" moved object becomes "consumed" by default when moved-from, so it is not necessary to write a special function to invalidate if not necessary (no need for [[clang::set_typestate(consumed)]]
).
b) constructors seem to leave the object in a consumed state by default (no need for [[clang::return_typestate(unconsumed)]]
);
CodePudding user response:
If a compiler isn't built with a setting to do this, then you can't make it do this. Use-after-move is a legitimate thing in C , so no compiler is obligated to consider it an error.
These kinds of things are what static analyzers are for.