blob: 89d4d082ed868f35556bdfa869db1368466dd6e5 [file] [log] [blame]
/* { dg-do link } */
/* { dg-options "-fno-allow-store-data-races" } */
/* { dg-final { simulate-thread } } */
#include <stdio.h>
#include "../../gcc.dg/simulate-thread/simulate-thread.h"
/* Test that we don't store past VAR.A. */
struct S
{
volatile unsigned int a : 4;
unsigned char b;
unsigned int c : 6;
} var = { 1, 2, 3 };
static int global = 0;
/* Called before each instruction, simulating another thread
executing. */
void simulate_thread_other_threads()
{
global++;
var.b = global;
/* Don't go past the 6 bits var.c can hold. */
var.c = global % 64;
}
/* Called after each instruction. Returns 1 if any inconsistency is
found, 0 otherwise. */
int simulate_thread_step_verify()
{
int ret = 0;
if (var.b != global)
{
printf("FAIL: invalid intermediate value for <b>.\n");
ret = 1;
}
if (var.c != global % 64)
{
printf("FAIL: invalid intermediate value for <c>.\n");
ret = 1;
}
return ret;
}
/* Called at the end of the program (simulate_thread_fini == 1). Verifies
the state of the program and returns 1 if any inconsistency is
found, 0 otherwise. */
int simulate_thread_final_verify()
{
if (var.a != 12)
{
printf("FAIL: invalid final result for <a>.\n");
return 1;
}
return 0;
}
__attribute__((noinline))
void simulate_thread_main()
{
var.a = 12;
}
int main()
{
simulate_thread_main();
simulate_thread_done();
return 0;
}