blob: 9a50732ef327a537809104a08fd81c123cb62282 [file] [log] [blame]
/* { dg-do run { target { ! *-*-* } } } */
/* { dg-additional-sources "../sync-1.c" } */
/* { dg-options "-Dop -Dtype=short -mno-unaligned-atomic-may-use-library" } */
/* Make sure we get a SIGTRAP or equivalent when passing unaligned
but otherwise valid pointers to the atomic builtins. */
#include <signal.h>
#include <stdlib.h>
#ifndef type
#error type not defined
#endif
#ifndef op
#define op 0
#endif
#ifndef xchg
#define xchg 0
#endif
#if op
int sfa (type *p, type *q, int a);
#endif
#if xchg
void acen (type *ptr, type *val, type *ret);
#endif
#ifndef misalignment
#define misalignment 1
#endif
volatile int trap_expected = 0;
struct { char x[misalignment]; type i; } s __attribute__ ((__aligned__ (4)))
= { {0}, (type) 0xdeadbeef };
type x = 2;
type ret = 42;
#ifdef TRAP_USING_ABORT
#define SYMSTR(x) STR1(__USER_LABEL_PREFIX__, x)
#define STR1(x,y) STR2(x, y)
#define STR2(x,y) #x #y
/* LTO requires marking seemingly-unused-but-used global functions. */
void my_abort (void) __asm__ (SYMSTR (abort)) __attribute__ ((__used__));
void my_abort (void)
#else
#error "can't catch break 8"
#endif
{
if (1
#ifndef TRAP_USING_ABORT
&& signum == SIGTRAP
#endif
&& trap_expected
&& s.i == (type) 0xdeadbeef
&& x == 2 && ret == 42)
exit (0);
#ifdef TRAP_USING_ABORT
/* We might be able to trust the exit-value getting through, but add
a NULL-dereference SEGV just in case. Make sure gcc doesn't
understand the NULL. */
*({ int *p; asm ("" : "=rm" (p) : "0" (0)); p; }) = 0xdead;
exit (2);
#else
abort ();
#endif
}
int main(void)
{
type ret;
#ifndef mis_ok
trap_expected = 1;
#endif
#if op
sfa (&s.i, &s.i, 42);
/* We should have fallen into the trap now. But don't call abort
yet: if the trap is implemented as a call to abort, we have to
tell the difference. Set a global variable *and* make sure the
setting isn't eliminated by optimizers: another call to sfa
should do it. */
trap_expected = 0;
#ifdef mis_ok
/* We're missing a sequence point, but we shouldn't have the initial
value. */
if (s.i == (type) 0xdeadbeef)
abort ();
exit (0);
#endif
sfa (&x, &x, 1);
#else
acen (&s.i, &x, &ret);
#ifdef mis_ok
if (s.i != 2 || x != 2 || ret != (type) 0xdeadbeef)
abort ();
exit (0);
#endif
trap_expected = 0;
acen (&x, &x, &ret);
#endif
abort ();
}