From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 8F70A3858433; Thu, 30 Sep 2021 16:41:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8F70A3858433 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-3989] libphobos: Select the appropriate exception handler in getClassInfo X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/master X-Git-Oldrev: ed3ec7343b7d104a3285336fbfc1e4719719f9b6 X-Git-Newrev: 8088a33df5f62fd6416fb8cb158b791e639aa707 Message-Id: <20210930164136.8F70A3858433@sourceware.org> Date: Thu, 30 Sep 2021 16:41:36 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Sep 2021 16:41:36 -0000 https://gcc.gnu.org/g:8088a33df5f62fd6416fb8cb158b791e639aa707 commit r12-3989-g8088a33df5f62fd6416fb8cb158b791e639aa707 Author: Iain Buclaw Date: Sat Sep 25 23:18:53 2021 +0200 libphobos: Select the appropriate exception handler in getClassInfo This is analogous to __gdc_personality, which ignores in-flight exceptions that we haven't collided with yet. libphobos/ChangeLog: * libdruntime/gcc/deh.d (ExceptionHeader.getClassInfo): Move to... (getClassInfo): ...here as free function. Add lsda parameter. (scanLSDA): Pass lsda to actionTableLookup. (actionTableLookup): Add lsda parameter, pass to getClassInfo. (__gdc_personality): Remove currentCfa variable. Diff: --- libphobos/libdruntime/gcc/deh.d | 74 ++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d index a7eb37cfd9e..ba57fed38dc 100644 --- a/libphobos/libdruntime/gcc/deh.d +++ b/libphobos/libdruntime/gcc/deh.d @@ -279,26 +279,6 @@ struct ExceptionHeader } } - /** - * Look at the chain of inflight exceptions and pick the class type that'll - * be looked for in catch clauses. - */ - static ClassInfo getClassInfo(_Unwind_Exception* unwindHeader) @nogc - { - ExceptionHeader* eh = toExceptionHeader(unwindHeader); - // The first thrown Exception at the top of the stack takes precedence - // over others that are inflight, unless an Error was thrown, in which - // case, we search for error handlers instead. - Throwable ehobject = eh.object; - for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next) - { - Error e = cast(Error)ehobject; - if (e is null || (cast(Error)ehn.object) !is null) - ehobject = ehn.object; - } - return ehobject.classinfo; - } - /** * Convert from pointer to unwindHeader to pointer to ExceptionHeader * that it is embedded inside of. @@ -666,7 +646,7 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti { // Otherwise we have a catch handler or exception specification. handler = actionTableLookup(actions, unwindHeader, actionRecord, - exceptionClass, TTypeBase, + lsda, exceptionClass, TTypeBase, TType, TTypeEncoding, saw_handler, saw_cleanup); } @@ -694,7 +674,8 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti * Look up and return the handler index of the classType in Action Table. */ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, - const(ubyte)* actionRecord, _Unwind_Exception_Class exceptionClass, + const(ubyte)* actionRecord, const(ubyte)* lsda, + _Unwind_Exception_Class exceptionClass, _Unwind_Ptr TTypeBase, const(ubyte)* TType, ubyte TTypeEncoding, out bool saw_handler, out bool saw_cleanup) @@ -702,7 +683,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, ClassInfo thrownType; if (isGdcExceptionClass(exceptionClass)) { - thrownType = ExceptionHeader.getClassInfo(unwindHeader); + thrownType = getClassInfo(unwindHeader, lsda); } while (1) @@ -778,6 +759,41 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader, return 0; } +/** + * Look at the chain of inflight exceptions and pick the class type that'll + * be looked for in catch clauses. + */ +ClassInfo getClassInfo(_Unwind_Exception* unwindHeader, + const(ubyte)* currentLsd) @nogc +{ + ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader); + // The first thrown Exception at the top of the stack takes precedence + // over others that are inflight, unless an Error was thrown, in which + // case, we search for error handlers instead. + Throwable ehobject = eh.object; + for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next) + { + const(ubyte)* nextLsd = void; + _Unwind_Ptr nextLandingPad = void; + _Unwind_Word nextCfa = void; + int nextHandler = void; + + ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa); + + // Don't combine when the exceptions are from different functions. + if (currentLsd != nextLsd) + break; + + Error e = cast(Error)ehobject; + if (e is null || (cast(Error)ehn.object) !is null) + { + currentLsd = nextLsd; + ehobject = ehn.object; + } + } + return ehobject.classinfo; +} + /** * Called when the personality function has found neither a cleanup or handler. * To support ARM EABI personality routines, that must also unwind the stack. @@ -934,16 +950,15 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions, // current object onto the end of the prevous object. ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader); auto currentLsd = lsda; - auto currentCfa = cfa; bool bypassed = false; while (eh.next) { ExceptionHeader* ehn = eh.next; - const(ubyte)* nextLsd; - _Unwind_Ptr nextLandingPad; - _Unwind_Word nextCfa; - int nextHandler; + const(ubyte)* nextLsd = void; + _Unwind_Ptr nextLandingPad = void; + _Unwind_Word nextCfa = void; + int nextHandler = void; ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa); @@ -952,14 +967,13 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions, { // We found an Error, bypass the exception chain. currentLsd = nextLsd; - currentCfa = nextCfa; eh = ehn; bypassed = true; continue; } // Don't combine when the exceptions are from different functions. - if (currentLsd != nextLsd && currentCfa != nextCfa) + if (currentLsd != nextLsd) break; // Add our object onto the end of the existing chain.