https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78495
Bug ID: 78495 Summary: [7 regression][new inheriting ctors] variant members lead to uninitialized parameter Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: lucdanton at free dot fr Target Milestone: --- I noticed an std::unique_ptr<int> destructor was being called on a bogus pointer in an own::optional<std::unique_ptr<int>> testcase of mine (not std::optional/libstdc++-related). I managed to reduce to a minimal test and in the debugger it looks like when the inherited constructor is entered the val parameter contains garbage. Then upon leaving the constructor the destructor for the parameter is run on that garbage. Whatever the exact rundown of events, the regression is that the program used to return 0 whereas it returns 1 now. The change in behaviour appeared with r241765. From then on, compiling the testcase with -fnew-inheriting-ctors gives the new behaviour while -fno-new-inheriting-ctors gives the old for both -std=c++1z and -std=c++14. //---------- int counter = 0; struct canary { canary() {} bool active = false; canary(canary const&) = delete; canary(canary&& other): active(other.active) { other.active = false; } ~canary() { if(active) ++counter; } }; struct optional_base { union { unsigned char empty {}; canary val; }; bool active = false; optional_base(canary val) : val(static_cast<canary&&>(val)) , active(true) {} ~optional_base() { if(active) { val.~canary(); } } }; struct optional: optional_base { using optional_base::optional_base; }; int main() { { // N.B. inactive from the start canary c; //assert( !c.active ); optional o(static_cast<canary&&>(c)); //assert( !c.active ); // may fire if -O level above 0 //assert( !o.val.active ); } return counter; }