From d7e5119b4c64a960ae66fdc0478e9658c9ebbf63 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 18 Oct 2014 13:58:19 -0700 Subject: Fix bug where Option destroys too much --- src/compat/option.hpp | 5 ++++- src/compat/option_test.cpp | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/compat') diff --git a/src/compat/option.hpp b/src/compat/option.hpp index 27ee0bc..1976589 100644 --- a/src/compat/option.hpp +++ b/src/compat/option.hpp @@ -171,7 +171,10 @@ namespace option } ~Option() { - do_destruct(); + if (repr.is_some()) + { + do_destruct(); + } } T move_or(T def) diff --git a/src/compat/option_test.cpp b/src/compat/option_test.cpp index b963a29..ac95424 100644 --- a/src/compat/option_test.cpp +++ b/src/compat/option_test.cpp @@ -117,6 +117,41 @@ TEST(Option, customrepr) } } +TEST(Option, destruct) +{ + struct BugCheck + { + bool *destroyed; + + BugCheck(bool *d) + : destroyed(d) + {} + BugCheck(BugCheck&& r) + : destroyed(r.destroyed) + { + r.destroyed = nullptr; + } + BugCheck& operator = (BugCheck&& r) + { + std::swap(destroyed, r.destroyed); + return *this; + } + ~BugCheck() + { + if (!destroyed) + return; + if (*destroyed) + abort(); + *destroyed = true; + } + }; + + bool destroyed = false; + + Option bug = Some(BugCheck(&destroyed)); + bug = None; +} + TEST(Option, def) { struct Tracked -- cgit v1.2.3-60-g2f50