检测对堆栈变量的调用delete(使用强制转换到指针运算符)

Detect calling delete on stack variables (with cast-to-pointer operator)

本文关键字:转换 指针 运算符 变量 堆栈 调用 delete 检测      更新时间:2023-10-16

tldr

有没有一种方法可以静态地检测以下代码中的错误?

struct Foo
{
    operator const int*()
    {
        return &data;
    }
    int data;
};
int main() 
{
    Foo f;
    delete f;
}

由于从Foo到void*的转换只包含一个用户定义的转换,因此实际上允许在f上调用delete

更长的故事

在我们的代码库中,有一种非常愚蠢的反序列化字符串的方法,即伪代码

char * buff = bar.loadString();
use buff;
delete buff;

方法被更改为一个模板化的加载函数,所以现在反序列化看起来像

bar.load(m_IntMember);
bar.load(m_StringMember);

loadString的所有出现(有很多(都必须手动更改,如下所示:

string buff;
bar.load(buff);
use buff;

我们都知道人为错误会导致什么,所以有些地方的代码被错误地修改了,比如

string buff;
bar.load(buff);
use buff;
delete buff;        //notice the delete

由于我们使用的是string的一个非标准实现,它实际上有一个overloaded const char * operator,它可以被广播到void*,可以被删除。。。

我想在编译时捕捉所有这些错误(我们有自定义的高性能分配器,所以在运行时,很容易损坏内存而不会出现任何运行时错误(

我无法声明全局删除运算符接受const char*我无法暂时从string中删除delete运算符,因为它被大量使用,所以没有它就无法编译(我无法从所有错误中"过滤掉"所描述的错误,因为msvc在达到一定的错误量时停止编译(

我能做什么?

这似乎做到了:

#include <iostream>
struct Foo
{
    Foo() : data(42) {}
    operator const int*()
    {
        return &data;
    }
    int data;
    struct AmbiguousPointerConversion {};
    private: operator AmbiguousPointerConversion *() {
        throw "hi";
    }
};
int main() 
{
    Foo f;
    const int *p = f;
    std::cout << *p << 'n';
    delete f;
}

用g++编译这个给了我:

try.cc: In function ‘int main()’:
try.cc:25:12: error: ambiguous default type conversion from ‘Foo’
     delete f;
            ^
try.cc:25:12: note:   candidate conversions include ‘Foo::operator const int*()’ and ‘Foo::operator Foo::AmbiguousPointerConversion*()’
try.cc:25:12: error: type ‘struct Foo’ argument given to ‘delete’, expected pointer