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

TL; DR

Is there a way to statically detect an error in the following code?

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

since there is a conversion from Foo to void * containing only one user-converted conversion, it is actually allowed to call delete on f .

longer story

in our code base, there was a really stupid way to deserialize strings in pseudo code

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

the method has been changed to one template loading function, so now deserialization looks like

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

but all occurrences (there were many) loadString had to be manually changed as follows:

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

We all know what human error can cause, so there are places where the code was incorrectly modified, for example

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

since we use the bit of the non-standard implementation of string , in fact it has an overloaded const char * operator , which can be dropped by void* , which can be removed ...

I would like to catch all these errors at compile time (we have custom high-performance allocators, so at runtime it easily corrupts memory without any runtime error)

I cannot declare a global delete operator accepting const char* I cannot temporarily remove the delete operator from string , because it is heavily used, so it cannot compile without it (I cannot "filter out" the described error from all errors, because msvc stops compilation when a certain number of errors are reached)

What can I do?

+5
source share
1 answer

It looks like this:

 #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; } 

Compiling with g ++ gives me:

 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 
+2
source

All Articles