Hi All, Could some gatekeeper please review this change?
The issue is as following: For a goto to outer block, the cleanup of local objects are needed. While, for call of destructor for each of them, the call is nested in a eh-region, as the destructor itself may throw exceptions. As we can see, the cleanup of such an eh-region, destructor of all remaining objects should be called. While, currently, open64 compiler would call destructor for all local objects, including the one being destructed. The case for an early exit is similar. The following is a test case to reproduce the issue. #include<iostream> class c1{ int i; public: c1(int j):i(j){}; ~c1(){ std::cout<<"destructing "<<i<<"\n"; if (i ==2 ) throw i; } }; int main() { try{ c1 o1(1); { c1 o2(2); goto s1; } }catch(int i){ } s1: try{ c1 o1(1); { c1 o2(2); return 1; } }catch(int i){ } return 0; } The fix is to temporarily modify the cleanup stack pointer, say, lower it for each clean-up being issued, and then restore the state. It should be safe as no new scope or objects would be introduced during this process. Best Regards, yiran Index: wgen_stmt.cxx =================================================================== --- wgen_stmt.cxx (revision 3338) +++ wgen_stmt.cxx (working copy) @@ -2133,13 +2133,17 @@ if (*li != *ci) break; if (ci!=Current_scope_nest.rend()) { + int scope_cleanup_i_save; + scope_cleanup_i_save = scope_cleanup_i; i = scope_cleanup_i; Is_True(i != -1, ("WGEN_Expand_Goto: scope_cleanup_stack empty")); while ((i >= 0) && (scope_cleanup_stack [i].stmt != *ci)) { + scope_cleanup_i --; Maybe_Emit_Cleanup (i, FALSE); --i; } + scope_cleanup_i = scope_cleanup_i_save; if (i == -1) { #ifdef FE_GNU_4_2_0 @@ -2291,8 +2295,10 @@ #endif int i = scope_cleanup_i; + int scope_cleanup_i_save = scope_cleanup_i; while (i != -1) { #ifdef KEY + scope_cleanup_i--; Maybe_Emit_Cleanup (i, FALSE); #else if (gs_tree_code(scope_cleanup_stack [i].stmt) == GS_CLEANUP_STMT) @@ -2301,6 +2307,7 @@ --i; } #ifdef KEY + scope_cleanup_i = scope_cleanup_i_save; if (emit_exceptions && processing_handler) { HANDLER_INFO hi = handler_stack.top(); FmtAssert (hi.scope, ("NULL scope")); @@ -2397,8 +2404,10 @@ #endif int i = scope_cleanup_i; + int scope_cleanup_i_save = scope_cleanup_i; while (i != -1) { #ifdef KEY + scope_cleanup_i--; Maybe_Emit_Cleanup (i, FALSE); #else if (gs_tree_code(scope_cleanup_stack [i].stmt) == GS_CLEANUP_STMT) @@ -2407,6 +2416,7 @@ --i; } #ifdef KEY + scope_cleanup_i = scope_cleanup_i_save; if (emit_exceptions && processing_handler) { HANDLER_INFO hi = handler_stack.top(); FmtAssert (hi.scope, ("NULL scope"));
------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________ Open64-devel mailing list Open64-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/open64-devel