Gcc 6.1.0 segmentation error - gcc error?

Let's look at the following code. This is actually a narrowed issue that I found with gmock and the mocking void (void) method.

class Base { public: virtual ~Base() {} }; class Derived : public Base { public: void GetValueAndDelete() { delete this; } //here we crash }; int main() { Derived* p = 0; p->GetValueAndDelete(); } 

Build with:

 /tools/gcc6.1/bin/g++ --version g++ (GCC) 6.1.0 

with an optimization level other than -O0, and executing the result leads to a segmentation error.

Is this a gcc bug or something with C ++ code (yes, yes, I know that it uses side effects, but it works with other compilers and without optimization)

0
source share
3 answers

This is gcc error

No.

or something with c ++ code

Yes. You are using an arrow operator on a pointer that does not point to a valid object. This has undefined behavior.

Highlighting the null pointer and calling method in such a way as not to use any elements is fine.

This is not normal according to the standard. This is UB.

What is a pointer invocation method?

The implementation is specific.

Removing this is nothing special.

Removing this is very special.

You should only take care not to use any item after

Yes, and you must make sure that to create all the instances for which this function is ever called, only new . No automatic objects, no static objects new[] , no malloc + placement of a new one.

So you can delete this , but be careful.

+4
source

Your intuition here is as follows:

  • p-> OK, because it's just the syntax to populate this .
  • delete this OK because you are not using this after delete .

But the above may not be in order, because dereferencing a null pointer is always undefined. Without optimizations enabled, this may not cause any problems, because the compiler executes the “base compiler”, which to some extent corresponds to what you imagine when you “compile in your mind”. However, with optimization, GCC will do many things that are usually not executed, for example, do not bother to correct the “correct” instructions when they encounter the wrong source code. There literally does not need to do anything when you say p-> as soon as your program runs - it can just pretend that main() was empty (or crash, as in your case).

+2
source

I know that the call method on nullptr is not standard, but so far I have not seen a compiler that could not handle this described way. Gcc6.1 seems to work differently (by spec). So this is a gmock bug. I wonder how many other projects depend on this compiler behavior :)

It is worth mentioning that this method is called, the 'this' inside is zero, as expected, and then removes the failure. I looked at the assembly, and there is mov (% rax),% rbx, which fails because rax contains zero.

0
source

Source: https://habr.com/ru/post/973535/


All Articles