c++ 在编译期间移动后检测使用?

rvpgvaaj  于 2023-05-08  发布在  其他
关注(0)|答案(2)|浏览(268)

clang-tidy静态分析器检测变量在移动后的使用。

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]

太棒了!

*如何让 * 编译器 、clang或GCC也检测到相同的问题?通过激活一些警告选项或通过一些(非标准?)属性?

我尝试在clang中使用-Wmove[[consumed]]属性,但它们没有帮助。也许我用错了。
代码在这里:https://godbolt.org/z/18hr4vn7x(下面的面板是clang-tidy,右边的中间面板是[empty]编译器输出)
编译器是否有可能对此发出警告,或者编译器检查此模式的成本太高?

wko9yo5t

wko9yo5t1#

我找到了一种方法,在clang中使用属性。。(GCC或更标准的解决方案仍然受欢迎。

1.需要clang 6或更高
1.将类标记为“可消耗”
1.将方法标记为“callable-when-unconsumed”(不确定如何将其设为默认值)

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
配方由https://awesomekling.github.io/Catching-use-after-move-bugs-with-Clang-consumed-annotations/简化而来。我找不到关于如何使用这些功能的 * 详细 * 文档。
之所以简化,是因为:
a)看起来“clang-consumable”移动的对象在moved-from时默认变为“consumed”,因此没有必要编写特殊的函数来无效(不需要[[clang::set_typestate(consumed)]])。
B)默认情况下,构造函数似乎使对象处于未使用状态(不需要[[clang::return_typestate(unconsumed)]]);

tkclm6bt

tkclm6bt2#

如果编译器在构建时没有设置这样做,那么你就不能让它这样做。use-after-move在C++中是合法的,因此没有编译器必须将其视为错误。
这类事情正是静态分析器的用途。

相关问题