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

            Bug ID: 80683
           Summary: Exceptions don't propagate through default member
                    initializer
           Product: gcc
           Version: 6.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: majerech.o at gmail dot com
  Target Milestone: ---

Testcase:

#include <iostream>
#include <stdexcept>

struct bar {
  bar() {
    throw std::runtime_error{"foo"};
  }
};

struct foo {
  bar b{};
};

int
main() try {
  foo f;
} catch (std::runtime_error& e) {
  std::cerr << e.what() << '\n';
}

Running this results in terminate being called:

terminate called after throwing an instance of 'std::runtime_error'
  what():  foo

I would very much expect this code to work – i.e. the exception should be
caught in main. This code does work on Clang 3.9.1 and I couldn't find any
reason in the standard for why the exception shouldn't be allowed to propagate.

Stepping through the code in GDB reveals that after throwing, the call-stack
unwinds all the way to foo's constructor and goes to std::terminate from there,
as if foo::foo() were noexcept.

Changing foo to

struct foo {
  bar b;
};

makes the bug go away. I.e. it only happens when a default member initializer
is used.

I've reproduced this on GCC 6.3.1 and GCC 8.0.0 20170507.

Reply via email to