[PSEH2_TEST]
[reactos.git] / rostests / tests / pseh2 / psehtest.c
index d8839e3..eb46701 100644 (file)
        DEALINGS IN THE SOFTWARE.
 */
 
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include <pseh/pseh2.h>
 
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
 #define STANDALONE
 #include <wine/test.h>
 
@@ -2410,6 +2402,112 @@ DEFINE_TEST(test_bug_4663)
 //}}}
 //}}}
 
+DEFINE_TEST(test_unvolatile)
+{
+    int val = 0;
+
+    _SEH2_TRY
+    {
+        val = return_one();
+        *((char*)0xc0000000) = 0;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        val = val + 3;
+    }
+    _SEH2_END;
+
+    return (val == 4);
+}
+
+DEFINE_TEST(test_unvolatile_2)
+{
+    int val = 0;
+
+    _SEH2_TRY
+    {
+        val = 1;
+        *((char*)0xc0000000) = 0;
+        val = 2;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        val = val + 3;
+    }
+    _SEH2_END;
+
+    return (val == 3) || (val == 4) || (val == 5);
+}
+
+DEFINE_TEST(test_finally_goto)
+{
+    volatile int val = 0;
+
+    _SEH2_TRY
+    {
+        val |= 1;
+        _SEH2_TRY
+        {
+            val |= 2;
+            goto next;
+        }
+        _SEH2_FINALLY
+        {
+            val |= 4;
+            *((char*)0xdeadc0de) = 0;
+            val |= 8;
+        }
+        _SEH2_END;
+
+        val |= 16;
+next:
+        val |= 32;
+        *((char*)0xdeadc0de) = 0;
+        val |= 64;
+    }
+    _SEH2_EXCEPT(1)
+    {
+        val |= 128;
+    }
+    _SEH2_END;
+
+    return (val == (128|4|2|1));
+}
+
+DEFINE_TEST(test_nested_exception)
+{
+    volatile int val = 0;
+
+    _SEH2_TRY
+    {
+        val |= 1;
+        _SEH2_TRY
+        {
+            val |= 2;
+            *((char*)0xdeadc0de) = 0;
+            val |= 4;
+        }
+        _SEH2_EXCEPT(1)
+        {
+            val |= 8;
+            *((char*)0xdeadc0de) = 0;
+            val |= 16;
+        }
+        _SEH2_END;
+
+        val |= 32;
+        *((char*)0xdeadc0de) = 0;
+        val |= 64;
+    }
+    _SEH2_EXCEPT(1)
+    {
+        val |= 128;
+    }
+    _SEH2_END;
+
+    return (val == (1|2|8|128));
+}
+
 static
 LONG WINAPI unhandled_exception(PEXCEPTION_POINTERS ExceptionInfo)
 {
@@ -2446,11 +2544,13 @@ int sanity_check(int ret, struct volatile_context * before, struct volatile_cont
        return ret;
 }
 
+#ifndef _PSEH3_H_
 static
 int passthrough_handler(struct _EXCEPTION_RECORD * e, void * f, struct _CONTEXT * c, void * d)
 {
        return ExceptionContinueSearch;
 }
+#endif
 
 static
 DECLSPEC_NOINLINE
@@ -2459,12 +2559,14 @@ int call_test(int (* func)(void))
        static int ret;
        static struct volatile_context before, after;
        static LPTOP_LEVEL_EXCEPTION_FILTER prev_unhandled_exception;
+#ifndef _PSEH3_H_
        static _SEH2Registration_t * prev_frame;
        _SEH2Registration_t passthrough_frame;
+#endif
 
        prev_unhandled_exception = SetUnhandledExceptionFilter(&unhandled_exception);
 
-#if defined(_X86_)
+#if defined(_X86_) && !defined(_PSEH3_H_)
        prev_frame = (_SEH2Registration_t *)__readfsdword(0);
        passthrough_frame.SER_Prev = prev_frame;
        passthrough_frame.SER_Handler = passthrough_handler;
@@ -2500,7 +2602,7 @@ int call_test(int (* func)(void))
        ret = func();
 #endif
 
-#if defined(_X86_)
+#if defined(_X86_) && !defined(_PSEH3_H_)
        if((_SEH2Registration_t *)__readfsdword(0) != &passthrough_frame || passthrough_frame.SER_Prev != prev_frame)
        {
                trace("exception registration list corrupted\n");
@@ -2514,6 +2616,28 @@ int call_test(int (* func)(void))
        return ret;
 }
 
+DEFINE_TEST(test_PSEH3_bug)
+{
+    volatile int count = 0;
+    int dummy = 0;
+
+    _SEH2_TRY
+    {
+        if (count++ == 0)
+        {
+            *(volatile int*)0x12345678 = 0x12345678;
+        }
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        dummy = 0;
+    }
+    _SEH2_END;
+
+    (void)dummy;
+    return (count == 1);
+}
+
 #define USE_TEST_NAME_(NAME_) # NAME_
 #define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_)
 #define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ }
@@ -2638,6 +2762,12 @@ void testsuite_syntax(void)
 
                USE_TEST(test_bug_4004),
                USE_TEST(test_bug_4663),
+
+               USE_TEST(test_unvolatile),
+               USE_TEST(test_unvolatile_2),
+               USE_TEST(test_finally_goto),
+               USE_TEST(test_nested_exception),
+               USE_TEST(test_PSEH3_bug),
        };
 
        size_t i;