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