[PSEH_TEST]
[reactos.git] / rostests / tests / pseh2 / psehtest.c
index 66cd6e5..dbd0e1e 100644 (file)
 
 #include <pseh/pseh2.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define STANDALONE
 #include <wine/test.h>
 
@@ -54,7 +58,11 @@ extern int return_minusone_4(void *, int);
 
 extern void set_positive(int *);
 
-static int call_test(int (*)(void));
+//static int call_test(int (*)(void));
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
 
 #define DEFINE_TEST(NAME_) static int NAME_(void)
 
@@ -2439,9 +2447,18 @@ DEFINE_TEST(test_unvolatile_2)
     return (val == 3) || (val == 4) || (val == 5);
 }
 
+/* This test is mainly for documentation purpose. As can be seen it doesn't
+   provide a satisfying result. In fact the compiler could do even more
+   crazy things like reusing val1 between the assignment to 0 and the last
+   assignment to 3. This DOES happen with C++ and it's NOT a PSEH bug, but
+   rather an unavoidable consequence of how the compiler works.
+   The conclusion: Do not use assignments to a variable inside a __try block
+   that is being used later inside the __except block, unless it is declared
+   volatile! */
+#ifndef __cplusplus
 DEFINE_TEST(test_unvolatile_3)
 {
-    int register val1 = 0, val2 = 0;
+    register int val1 = 0, val2 = 0;
 
     _SEH2_TRY
     {
@@ -2486,6 +2503,26 @@ DEFINE_TEST(test_unvolatile_3)
 
     return FALSE;
 }
+#endif // __cplusplus
+
+DEFINE_TEST(test_unvolatile_4)
+{
+    unsigned result = 0xdeadbeef;
+
+    _SEH2_TRY
+    {
+        *(char*)0x80000000 = 1;
+    }
+    _SEH2_EXCEPT(result == 0xdeadbeef)
+    {
+        result = 2;
+    }
+    _SEH2_END;
+
+    result = (result == 0xdeadbeef) ? 0 : result + 1;
+
+    return result == 3;
+}
 
 DEFINE_TEST(test_finally_goto)
 {
@@ -2583,7 +2620,7 @@ static
 DECLSPEC_NOINLINE
 int sanity_check(int ret, struct volatile_context * before, struct volatile_context * after)
 {
-       if(ret && memcmp(before, after, sizeof(before)))
+       if(ret && memcmp(before, after, sizeof(*before)))
        {
                trace("volatile context corrupted\n");
                return 0;
@@ -2686,6 +2723,33 @@ DEFINE_TEST(test_PSEH3_bug)
     return (count == 1);
 }
 
+void
+use_lots_of_stack(void)
+{
+    int i;
+    volatile int arr[512];
+    for (i = 0; i < 512; i++)
+        arr[i] = 123;
+    (void)arr;
+}
+
+DEFINE_TEST(test_PSEH3_bug2)
+{
+    unsigned long status = 0;
+    _SEH2_TRY
+    {
+        *(volatile int*)0x12345678 = 0x12345678;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        use_lots_of_stack();
+        status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    return (status == STATUS_ACCESS_VIOLATION);
+}
+
 #define USE_TEST_NAME_(NAME_) # NAME_
 #define USE_TEST_NAME(NAME_) USE_TEST_NAME_(NAME_)
 #define USE_TEST(NAME_) { USE_TEST_NAME(NAME_), NAME_ }
@@ -2813,10 +2877,14 @@ void testsuite_syntax(void)
 
                USE_TEST(test_unvolatile),
                USE_TEST(test_unvolatile_2),
+#ifndef __cplusplus
                USE_TEST(test_unvolatile_3),
+#endif
+               USE_TEST(test_unvolatile_4),
                USE_TEST(test_finally_goto),
                USE_TEST(test_nested_exception),
                USE_TEST(test_PSEH3_bug),
+               USE_TEST(test_PSEH3_bug2),
        };
 
        size_t i;