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("---");
+}