[PATCH] vcruntime140_1: Terminate on noexcept function trying to propagate exception.

Daniel Lehman dlehman25 at gmail.com
Tue Sep 29 23:49:30 CDT 2020


Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>

---
this should print 0x42:
wine64 tosend.exe

these should terminate():
wine64 tosend.exe 1
wine64 tosend.exe 1 1

/* cl /EHsc /MD noexcept.cpp */

void do_throw(void) { throw int(0x42); }

void crash_without_tries(void) noexcept { do_throw(); }

void crash_with_tries(void) noexcept
{
    try { do_throw(); } catch (float e) { /* bogus */ }
}

void works(void) noexcept
{
    try { do_throw(); } catch (int e) { printf("0x%x\n", e); }
}

int main(int argc, char **argv)
{
    try
    {
        switch (argc)
        {
            case 3: crash_without_tries(); break;
            case 2: crash_with_tries(); break;
            default: works(); break;
        }
    }
    catch (...)
    {
        printf("%s: should not be printed\n", __FUNCTION__);
    }
    return 0;
}

Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
 dlls/vcruntime140_1/except_x86_64.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/dlls/vcruntime140_1/except_x86_64.c b/dlls/vcruntime140_1/except_x86_64.c
index f66ae43721f..9d5757748d2 100644
--- a/dlls/vcruntime140_1/except_x86_64.c
+++ b/dlls/vcruntime140_1/except_x86_64.c
@@ -741,6 +741,7 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec,
 {
     cxx_function_descr descr;
     BYTE *p, *count, *count_end;
+    EXCEPTION_DISPOSITION ret;
     int trylevel;
 
     TRACE("%p %lx %p %p\n", rec, frame, context, dispatch);
@@ -759,7 +760,7 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec,
         return ExceptionContinueSearch;  /* handle only c++ exceptions */
 
     if (descr.header & ~(FUNC_DESCR_IS_CATCH | FUNC_DESCR_UNWIND_MAP |
-                FUNC_DESCR_TRYBLOCK_MAP | FUNC_DESCR_EHS))
+                FUNC_DESCR_TRYBLOCK_MAP | FUNC_DESCR_EHS | FUNC_DESCR_NO_EXCEPT))
     {
         FIXME("unsupported flags: %x\n", descr.header);
         return ExceptionContinueSearch;
@@ -789,7 +790,16 @@ EXCEPTION_DISPOSITION __cdecl __CxxFrameHandler4(EXCEPTION_RECORD *rec,
     if (!validate_cxx_function_descr4(&descr, dispatch))
         return ExceptionContinueSearch;
 
-    return cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel);
+    ret = cxx_frame_handler4(rec, frame, context, dispatch, &descr, trylevel);
+    if (descr.header & FUNC_DESCR_NO_EXCEPT &&
+        !(rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) &&
+        ret == ExceptionContinueSearch)
+    {
+        ERR("noexcept function propagating exception\n");
+        terminate();
+    }
+
+    return ret;
 }
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
-- 
2.25.1




More information about the wine-devel mailing list