diff options
Diffstat (limited to 'gcc/testsuite/g++.dg/simulate-thread')
-rw-r--r-- | gcc/testsuite/g++.dg/simulate-thread/atomics-1.C | 73 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/simulate-thread/atomics-2.C | 58 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C | 77 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/simulate-thread/bitfields.C | 80 |
4 files changed, 288 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C b/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C new file mode 100644 index 00000000000..7e0041ee382 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/atomics-1.C @@ -0,0 +1,73 @@ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that atomic int and atomic char work properly. */ + +using namespace std; + +#include <atomic> +#include <limits.h> +#include <stdio.h> +#include "simulate-thread.h" + +atomic<int> atomi; +atomic<char> atomc; + +/* No need for parallel threads to do anything */ +void simulate_thread_other_threads() +{ +} + +/* Verify after every instruction is executed, that the atmoic int and + char have one of the 2 legitimate values. */ +int simulate_thread_step_verify() +{ + if (atomi != 0 && atomi != INT_MAX) + { + printf ("FAIL: invalid intermediate result for atomi (%d).\n", + (int)atomi); + return 1; + } + if (atomc != 0 && atomc != CHAR_MAX) + { + printf ("FAIL: invalid intermediate result for atomc (%d).\n", + (int)atomc); + return 1; + } + return 0; +} + + +/* Verify that both atmoics have the corerct value. */ +int simulate_thread_final_verify() +{ + if (atomi != INT_MAX) + { + printf ("FAIL: invalid final result for atomi (%d).\n", + (int)atomi); + return 1; + } + if (atomc != CHAR_MAX) + { + printf ("FAIL: invalid final result for atomc (%d).\n", + (int)atomc); + return 1; + } + return 0; +} + +/* Test a store to an atomic int and an atomic char. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + atomi = INT_MAX; + atomc = CHAR_MAX; +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C b/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C new file mode 100644 index 00000000000..be3232d7087 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/atomics-2.C @@ -0,0 +1,58 @@ +/* { dg-do link } */ +/* { dg-options "-std=c++0x" } */ +/* { dg-final { simulate-thread } } */ + +using namespace std; + +#include <atomic> +#include <limits.h> +#include <stdio.h> +#include "simulate-thread.h" + +atomic_int atomi; + +/* Non-atomic. Use a type wide enough to possibly coerce GCC into + moving things around. */ +long double j; + + +/* Test that an atomic store synchronizes with an atomic load. + + In this case, test that the store to <j> happens-before the atomic + store to <atomi>. Make sure the compiler does not reorder the + stores. */ +__attribute__((noinline)) +void simulate_thread_main() +{ + j = 13.0; + atomi.store(1); +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} + +void simulate_thread_other_threads() +{ +} + +/* Verify that side-effects before an atomic store are correctly + synchronized with the an atomic load to the same location. */ +int simulate_thread_step_verify() +{ + if (atomi.load() == 1 && j != 13.0) + { + printf ("FAIL: invalid synchronization for atomic load/store.\n"); + return 1; + } + return 0; +} + + +int simulate_thread_final_verify() +{ + return simulate_thread_step_verify(); +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C new file mode 100644 index 00000000000..077514a3ff5 --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields-2.C @@ -0,0 +1,77 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-load-data-races=0 --param allow-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that setting <var.a> does not touch either <var.b> or <var.c>. + In the C++ memory model, non contiguous bitfields ("a" and "c" + here) should be considered as distinct memory locations, so we + can't use bit twiddling to set either one. */ + +#include <stdio.h> +#include "simulate-thread.h" + +#define CONSTA 12 + +static int global; +struct S +{ + unsigned int a : 4; + unsigned char b; + unsigned int c : 6; +} var; + +__attribute__((noinline)) +void set_a() +{ + var.a = CONSTA; +} + +void simulate_thread_other_threads() +{ + ++global; + var.b = global; + var.c = global; +} + +int simulate_thread_step_verify() +{ + int ret = 0; + if (var.b != global) + { + printf ("FAIL: Unexpected value: var.b is %d, should be %d\n", + var.b, global); + ret = 1; + } + if (var.c != global) + { + printf ("FAIL: Unexpected value: var.c is %d, should be %d\n", + var.c, global); + ret = 1; + } + return ret; +} + +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify(); + if (var.a != CONSTA) + { + printf ("FAIL: Unexpected value: var.a is %d, should be %d\n", + var.a, CONSTA); + ret = 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + set_a(); +} + +int main() +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/simulate-thread/bitfields.C b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C new file mode 100644 index 00000000000..3acf21f876f --- /dev/null +++ b/gcc/testsuite/g++.dg/simulate-thread/bitfields.C @@ -0,0 +1,80 @@ +/* { dg-do link } */ +/* { dg-options "--param allow-load-data-races=0 --param allow-store-data-races=0" } */ +/* { dg-final { simulate-thread } } */ + +/* Test that setting <var.a> does not touch either <var.b> or <var.c>. + In the C++ memory model, non contiguous bitfields ("a" and "c" + here) should be considered as distinct memory locations, so we + can't use bit twiddling to set either one. */ + +#include <stdio.h> +#include "simulate-thread.h" + +#define CONSTA 12 + +static int global; +struct S +{ + /* On x86-64, the volatile causes us to access <a> with a 32-bit + access, and thus trigger this test. */ + volatile unsigned int a : 4; + + unsigned char b; + unsigned int c : 6; +} var; + +__attribute__((noinline)) +void set_a() +{ + var.a = CONSTA; +} + +void simulate_thread_other_threads() +{ + ++global; + var.b = global; + var.c = global; +} + +int simulate_thread_step_verify() +{ + int ret = 0; + if (var.b != global) + { + printf ("FAIL: Unexpected value: var.b is %d, should be %d\n", + var.b, global); + ret = 1; + } + if (var.c != global) + { + printf ("FAIL: Unexpected value: var.c is %d, should be %d\n", + var.c, global); + ret = 1; + } + return ret; +} + +int simulate_thread_final_verify() +{ + int ret = simulate_thread_step_verify(); + if (var.a != CONSTA) + { + printf ("FAIL: Unexpected value: var.a is %d, should be %d\n", + var.a, CONSTA); + ret = 1; + } + return ret; +} + +__attribute__((noinline)) +void simulate_thread_main() +{ + set_a(); +} + +int main () +{ + simulate_thread_main(); + simulate_thread_done(); + return 0; +} |