testsuite/ * lib/gcc-memmodel-gdb-test.exp: Return if no executable. * gcc.dg/memmodel/memmodel.h (memmodel_done): Add noinline attribute. * g++.dg/memmodel/bitfields.C: New. Index: testsuite/lib/gcc-memmodel-gdb-test.exp =================================================================== --- testsuite/lib/gcc-memmodel-gdb-test.exp (revision 170852) +++ testsuite/lib/gcc-memmodel-gdb-test.exp (working copy) @@ -35,6 +35,10 @@ proc memmodel-gdb-test { } { set exec_file "[file rootname [file tail $prog]].exe" set cmd_file "$testsuite_dir/gcc.dg/memmodel/memmodel.gdb" + if ![file exists $exec_file] { + return + } + send_log "Spawning: $gdb_name -nx -nw -quiet -x $cmd_file ./$exec_file\n" set res [remote_spawn target "$gdb_name -nx -nw -x $cmd_file ./$exec_file"] if { $res < 0 || $res == "" } { Index: testsuite/gcc.dg/memmodel/memmodel.h =================================================================== --- testsuite/gcc.dg/memmodel/memmodel.h (revision 170852) +++ testsuite/gcc.dg/memmodel/memmodel.h (working copy) @@ -1,6 +1,6 @@ int memmodel_fini = 0; -void +void __attribute__((noinline)) memmodel_done () { memmodel_fini = 1; Index: testsuite/g++.dg/memmodel/bitfields.C =================================================================== --- testsuite/g++.dg/memmodel/bitfields.C (revision 0) +++ testsuite/g++.dg/memmodel/bitfields.C (revision 0) @@ -0,0 +1,73 @@ +/* { dg-do link } */ +/* { dg-options "-O2 --param allow-load-data-races=0 --param allow-store-data-races=0" } */ +/* { dg-final { memmodel-gdb-test } } */ + +/* Test that setting does not touch either or . + 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 +#include "memmodel.h" + +#define CONSTA 12 + +static int global; +struct S +{ + /* On x86-64, the volatile causes us to access with a 32-bit + access, and thus trigger this test. */ + volatile unsigned int a : 4; + + unsigned char b; + unsigned int c : 6; +} var; + +void set_a() +{ + var.a = CONSTA; +} + +void memmodel_other_threads() +{ + ++global; + var.b = global; + var.c = global; +} + +int memmodel_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 memmodel_final_verify() +{ + int ret = memmodel_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; +} + +int main() +{ + set_a(); + memmodel_done(); + return 0; +}