diff gcc/testsuite/gcc.dg/c11-atomic-1.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/gcc.dg/c11-atomic-1.c	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,267 @@
+/* Test for _Atomic in C11.  Test of valid code.  See c11-atomic-2.c
+   for more exhaustive tests of assignment cases.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+/* The use of _Atomic as a qualifier, and of _Atomic (type-name), give
+   the same type.  */
+extern _Atomic int a;
+extern _Atomic (int) a;
+extern int *_Atomic b;
+extern _Atomic (int *) b;
+extern void f (int [_Atomic]);
+extern void f (int *_Atomic);
+
+/* _Atomic may be applied to arbitrary types, with or without other
+   qualifiers, and assignments may be made as with non-atomic
+   types.  Structure and union elements may be atomic.  */
+_Atomic int ai1, ai2;
+int i1;
+volatile _Atomic long double ald1;
+const _Atomic long double ald2;
+long double ld1;
+_Atomic _Complex double acd1, acd2;
+_Complex double d1;
+_Atomic volatile _Bool ab1;
+int *p;
+int *_Atomic restrict ap;
+struct s { char c[1000]; };
+_Atomic struct s as1;
+struct s s1;
+struct t { _Atomic int i; };
+_Atomic struct t at1;
+_Atomic struct t *atp1;
+struct t t1;
+union u { char c[1000]; };
+_Atomic union u au1;
+union u u1;
+union v { _Atomic int i; };
+_Atomic union v av1;
+union v v1;
+
+void
+func (_Atomic volatile long al1)
+{
+  ai1 = ai2;
+  ai1 = i1;
+  i1 = ai2;
+  ai1 = ald2;
+  ald1 = d1;
+  ld1 = acd2;
+  acd1 += ab1;
+  acd2 /= ai1;
+  p = ap;
+  ap = p;
+  ab1 = p;
+  as1 = s1;
+  s1 = as1;
+  at1 = t1;
+  t1 = at1;
+  /* It's unclear whether the undefined behavior (6.5.2.3#5) for
+     accessing elements of atomic structures and unions is at
+     translation or execution time; presume here that it's at
+     execution time.  */
+  t1.i = at1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
+  at1.i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
+  atp1->i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */
+  au1 = u1;
+  u1 = au1;
+  av1 = v1;
+  v1 = av1;
+  v1.i = av1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */
+  av1.i = v1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */
+  /* _Atomic is valid on register variables, even if not particularly
+     useful.  */
+  register _Atomic volatile int ra1 = 1, ra2 = 2;
+  ra1 = ra2;
+  ra2 = ra1;
+  /* And on parameters.  */
+  al1 = ra1;
+  ra2 = al1;
+}
+
+/* A function may return an atomic type.  */
+_Atomic int
+func2 (int i)
+{
+  return i;
+}
+
+/* Casts may specify atomic type.  */
+int
+func3 (int i)
+{
+  return func2 ((_Atomic long) i);
+}
+
+/* The _Atomic void type is valid.  */
+_Atomic void *avp;
+
+/* An array of atomic elements is valid (the elements being atomic,
+   not the array).  */
+_Atomic int aa[10];
+int
+func4 (void)
+{
+  return aa[2];
+}
+
+/* Increment and decrement are valid for atomic types when they are
+   valid for non-atomic types.  */
+void
+func5 (void)
+{
+  ald1++;
+  ald1--;
+  ++ald1;
+  --ald1;
+  ai1++;
+  ai1--;
+  ++ai1;
+  --ai1;
+  ab1++;
+  ab1--;
+  ++ab1;
+  --ab1;
+  ap++;
+  ap--;
+  ++ap;
+  --ap;
+}
+
+/* Compound literals may have atomic type.  */
+_Atomic int *aiclp = &(_Atomic int) { 1 };
+
+/* Test unary & and *.  */
+void
+func6 (void)
+{
+  int i = *aiclp;
+  _Atomic int *p = &ai2;
+}
+
+/* Casts to atomic type are valid (although the _Atomic has little
+   effect because the result is an rvalue).  */
+int i2 = (_Atomic int) 1.0;
+
+/* For pointer subtraction and comparisons, _Atomic does not count as
+   a qualifier.  Likewise for conditional expressions.  */
+_Atomic int *xaip1;
+volatile _Atomic int *xaip2;
+void *xvp1;
+
+void
+func7 (void)
+{
+  int r;
+  r = xaip1 - xaip2;
+  r = xaip1 < xaip2;
+  r = xaip1 > xaip2;
+  r = xaip1 <= xaip2;
+  r = xaip1 >= xaip2;
+  r = xaip1 == xaip2;
+  r = xaip1 != xaip2;
+  r = xaip1 == xvp1;
+  r = xaip1 != xvp1;
+  r = xvp1 == xaip1;
+  r = xvp1 != xaip1;
+  r = xaip1 == 0;
+  r = ((void *) 0) == xaip2;
+  (void) (r ? xaip1 : xaip2);
+  (void) (r ? xvp1 : xaip2);
+  (void) (r ? xaip2 : xvp1);
+  (void) (r ? xaip1 : 0);
+  (void) (r ? 0 : xaip1);
+  /* The result of a conditional expression between a pointer to
+     qualified or unqualified (but not atomic) void, and a pointer to
+     an atomic type, is a pointer to appropriately qualified, not
+     atomic, void.  As such, it is valid to use further in conditional
+     expressions with other pointer types.  */
+  (void) (r ? xaip1 : (r ? xaip1 : xvp1));
+}
+
+/* Pointer += and -= integer is valid.  */
+void
+func8 (void)
+{
+  b += 1;
+  b -= 2ULL;
+  ap += 3;
+}
+
+/* Various other cases of simple assignment are valid (some already
+   tested above).  */
+void
+func9 (void)
+{
+  ap = 0;
+  ap = (void *) 0;
+  xvp1 = atp1;
+  atp1 = xvp1;
+}
+
+/* Test compatibility of function types in cases where _Atomic matches
+   (see c11-atomic-3.c for corresponding cases where it doesn't
+   match).  */
+void fc0a (int const);
+void fc0a (int);
+void fc0b (int _Atomic);
+void fc0b (int _Atomic);
+void fc1a (int);
+void
+fc1a (x)
+     volatile int x;
+{
+}
+void fc1b (_Atomic int);
+void
+fc1b (x)
+     volatile _Atomic int x;
+{
+}
+void
+fc2a (x)
+     const int x;
+{
+}
+void fc2a (int); /* { dg-warning "follows non-prototype" } */
+void
+fc2b (x)
+     _Atomic int x;
+{
+}
+void fc2b (_Atomic int); /* { dg-warning "follows non-prototype" } */
+void fc3a (int);
+void
+fc3a (x)
+     volatile short x;
+{
+}
+void fc3b (_Atomic int);
+void
+fc3b (x)
+     _Atomic short x;
+{
+}
+void
+fc4a (x)
+     const short x;
+{
+}
+void fc4a (int); /* { dg-warning "follows non-prototype" } */
+void
+fc4b (x)
+     _Atomic short x;
+{
+}
+void fc4b (_Atomic int); /* { dg-warning "follows non-prototype" } */
+
+/* Test cases involving C_MAYBE_CONST_EXPR work.  */
+void
+func10 (_Atomic int *p)
+{
+  p[0 / 0] = 1; /* { dg-warning "division by zero" } */
+  p[0 / 0] += 1; /* { dg-warning "division by zero" } */
+  *p = 0 / 0; /* { dg-warning "division by zero" } */
+  *p += 0 / 0; /* { dg-warning "division by zero" } */
+}