https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95741

            Bug ID: 95741
           Summary: Optimization  removes call to set_terminate in
                    destructor
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mpoulhies at kalray dot eu
  Target Milestone: ---

The following code has different executions in O0 and O3.
It looks like GCC is able to optimize the `throw s` in `test()` by calling
`terminate()` directly as it knows the destructor will raise an exception:

```
terminate called after throwing an instance of 'int'
Aborted
```

But without optimization, the destructor will be executed and the
`set_terminate` function will hook `my_term` and the program will return 0.

I'm not sure if this is a valid optimization and the original code is wrong, or
if the code is valid.

I've tried with various GCC version from 7.5 to 10.1.0.

#include <exception>
#include <unistd.h>

int test ( void );

void my_term ( void )
{
  // only way to exit SUCCESS
  _exit(0);
}

int main(void)
{
  test ();

  // unreachable
  return 1;
}


struct S1 {
public:
  ~S1 (  ) noexcept (false)
  {
    // moving this outside of ~S1 (eg. in main()) makes the program behave
    // consistently for O0~O3
    std::set_terminate(&my_term);

    // this should trigger the terminate() as we are throwing in a dtor called
    // during exception handling ?
    throw 1;
  };
};


int test(void)
{
  try
    {
      int s = 0;
      S1  ss;

      // this should trigger the dtor for ss
      throw s;

      // unreachable
      return -1;
    }
  catch ( ... ) {
    // unreachable
    return -1;
  }
}

Reply via email to