diff --git a/semantics/common/execution/thread_local.k b/semantics/common/execution/thread_local.k index 46dd1a41f..ec1dda1f8 100644 --- a/semantics/common/execution/thread_local.k +++ b/semantics/common/execution/thread_local.k @@ -49,6 +49,7 @@ module COMMON-THREAD-LOCAL .K // object being constructed .K + .List // most derived class being constructed .K @@ -82,7 +83,6 @@ module COMMON-THREAD-LOCAL // used to store the catch handlers if this // block is a try block in C++ .List - .K // used to control initialization when gotoing @@ -99,6 +99,7 @@ module COMMON-THREAD-LOCAL // Used to catch potential stack size overflows. 0 + .K false // stdarg diff --git a/semantics/cpp/language/execution/binding.k b/semantics/cpp/language/execution/binding.k index ed0c6dfca..febb7868f 100644 --- a/semantics/cpp/language/execution/binding.k +++ b/semantics/cpp/language/execution/binding.k @@ -56,11 +56,19 @@ module CPP-EXECUTION-BINDING _ => Obj rule beginConstruction(Obj:LVal, IsBaseClassSubobject:Bool) => Obj ... - _ => Obj - MostDerived:K => #if IsBaseClassSubobject #then MostDerived #else type(Obj) #fi + Old::K => Obj + + .List => ListItem(Old) + ... + + MostDerived:K => #if IsBaseClassSubobject #then MostDerived #else type(Obj) #fi + rule endConstruction(Obj:LVal, IsConstructor::Bool) => finishConstruction(Obj, IsConstructor) ... - _ => .K + _ => Old + + ListItem( Old::K ) => .List + ... rule finishConstruction(Obj:LVal, IsConstructor:Bool) => Obj ... .List => diff --git a/semantics/cpp/language/execution/stmt/try.k b/semantics/cpp/language/execution/stmt/try.k index 3050a6202..d200bc6c4 100644 --- a/semantics/cpp/language/execution/stmt/try.k +++ b/semantics/cpp/language/execution/stmt/try.k @@ -196,8 +196,9 @@ module CPP-EXECUTION-STMT-TRY rule activateHandler => .K ... _ => false - rule deactivateHandler => .K ... - _ => .K + // @ref n4296 15.1/4 + rule deactivateHandler => destructLocal(false, lcentry(V, true, true, false)) ... + V::LVal => .K rule tryMark(_) => .K diff --git a/tests/unit-pass/copy-construction.C b/tests/unit-pass/copy-construction.C new file mode 100644 index 000000000..266fb8495 --- /dev/null +++ b/tests/unit-pass/copy-construction.C @@ -0,0 +1,18 @@ +struct E { + E(){} + ~E(){} + E(E const &){} + int x; +}; + +E foo() { + return E(); + //return {}; +} + +int main() { + foo(); + //E(E()); + E e = E(); + try { throw E(); } catch(...){} +} diff --git a/tests/unit-pass/destruct-thrown.C b/tests/unit-pass/destruct-thrown.C new file mode 100644 index 000000000..9c00bfef3 --- /dev/null +++ b/tests/unit-pass/destruct-thrown.C @@ -0,0 +1,15 @@ +extern "C" int puts(char const *); + +struct E { + int x = 0; + E(){puts("E()");} + ~E(){puts("~E()");} + E(E const &){puts("E(E const &)");} +}; + +int main() { + try { + throw E(); + } catch(E const &e) {} + puts("---"); +}