175 lines
7.0 KiB
C
175 lines
7.0 KiB
C
/* Test for _Atomic in C11. Test of invalid code. */
|
|
/* { dg-do compile } */
|
|
/* { dg-options "-std=c11 -pedantic-errors" } */
|
|
|
|
/* Increment and decrement are invalid for atomic complex types and
|
|
atomic pointers to incomplete types, just as for the corresponding
|
|
non-atomic types. Likewise for types on which arithmetic is
|
|
invalid. */
|
|
_Atomic _Complex float acf;
|
|
void *_Atomic apv;
|
|
struct s *_Atomic aps;
|
|
_Atomic struct t { char c; } as;
|
|
|
|
void
|
|
func (void)
|
|
{
|
|
acf++; /* { dg-error "complex types" } */
|
|
acf--; /* { dg-error "complex types" } */
|
|
++acf; /* { dg-error "complex types" } */
|
|
--acf; /* { dg-error "complex types" } */
|
|
apv++; /* { dg-error "wrong type|pointer of type" } */
|
|
apv--; /* { dg-error "wrong type|pointer of type" } */
|
|
++apv; /* { dg-error "wrong type|pointer of type" } */
|
|
--apv; /* { dg-error "wrong type|pointer of type" } */
|
|
aps++; /* { dg-error "pointer to|invalid use of undefined type" } */
|
|
aps--; /* { dg-error "pointer to|invalid use of undefined type" } */
|
|
++aps; /* { dg-error "pointer to|invalid use of undefined type" } */
|
|
--aps; /* { dg-error "pointer to|invalid use of undefined type" } */
|
|
as++; /* { dg-error "wrong type" } */
|
|
as--; /* { dg-error "wrong type" } */
|
|
++as; /* { dg-error "wrong type" } */
|
|
--as; /* { dg-error "wrong type" } */
|
|
}
|
|
|
|
/* Pointer subtraction and comparisons differing in _Atomic are
|
|
invalid where such subtraction and comparisons differing in
|
|
qualifiers are valid. There is no special allowance for equality
|
|
comparisons of pointers to atomic void to pointers to object
|
|
types. Likewise for conditional expressions. */
|
|
int *pi;
|
|
_Atomic int *pai;
|
|
_Atomic void *pav;
|
|
int r;
|
|
|
|
void
|
|
func2 (void)
|
|
{
|
|
r = pai - pi; /* { dg-error "invalid operands" } */
|
|
r = pi - pai; /* { dg-error "invalid operands" } */
|
|
r = pi < pai; /* { dg-error "distinct pointer types" } */
|
|
r = pi > pai; /* { dg-error "distinct pointer types" } */
|
|
r = pi <= pai; /* { dg-error "distinct pointer types" } */
|
|
r = pi >= pai; /* { dg-error "distinct pointer types" } */
|
|
r = pai < pi; /* { dg-error "distinct pointer types" } */
|
|
r = pai > pi; /* { dg-error "distinct pointer types" } */
|
|
r = pai <= pi; /* { dg-error "distinct pointer types" } */
|
|
r = pai >= pi; /* { dg-error "distinct pointer types" } */
|
|
r = pav == pi; /* { dg-error "distinct pointer types" } */
|
|
r = pav != pi; /* { dg-error "distinct pointer types" } */
|
|
r = pi == pav; /* { dg-error "distinct pointer types" } */
|
|
r = pi != pav; /* { dg-error "distinct pointer types" } */
|
|
(void) (r ? pai : pi); /* { dg-error "pointer type mismatch" } */
|
|
(void) (r ? pi : pai); /* { dg-error "pointer type mismatch" } */
|
|
(void) (r ? pai : pav); /* { dg-error "pointer type mismatch" } */
|
|
(void) (r ? pav : pai); /* { dg-error "pointer type mismatch" } */
|
|
}
|
|
|
|
/* Likewise for pointer assignment. */
|
|
void
|
|
func3 (void)
|
|
{
|
|
pai = pi; /* { dg-error "incompatible pointer type" } */
|
|
pi = pai; /* { dg-error "incompatible pointer type" } */
|
|
pav = pai; /* { dg-error "incompatible pointer type" } */
|
|
pai = pav; /* { dg-error "incompatible pointer type" } */
|
|
}
|
|
|
|
/* Cases that are invalid for normal assignments are just as invalid
|
|
(and should not ICE) when the LHS is atomic. */
|
|
void
|
|
func4 (void)
|
|
{
|
|
as = acf; /* { dg-error "incompatible types" } */
|
|
apv = as; /* { dg-error "incompatible types" } */
|
|
as += 1; /* { dg-error "invalid operands" } */
|
|
apv -= 1; /* { dg-error "pointer of type" } */
|
|
apv *= 1; /* { dg-error "invalid operands" } */
|
|
apv /= 1; /* { dg-error "invalid operands" } */
|
|
apv %= 1; /* { dg-error "invalid operands" } */
|
|
apv <<= 1; /* { dg-error "invalid operands" } */
|
|
apv >>= 1; /* { dg-error "invalid operands" } */
|
|
apv &= 1; /* { dg-error "invalid operands" } */
|
|
apv ^= 1; /* { dg-error "invalid operands" } */
|
|
apv |= 1; /* { dg-error "invalid operands" } */
|
|
}
|
|
|
|
/* We don't allow atomic bit-fields in GCC (implementation-defined
|
|
whether they are permitted). */
|
|
struct abf
|
|
{
|
|
_Atomic int i : 1; /* { dg-error "atomic type" } */
|
|
_Atomic int : 0; /* { dg-error "atomic type" } */
|
|
};
|
|
|
|
/* _Atomic (type-name) may not use a name for an array, function,
|
|
qualified or atomic type. */
|
|
_Atomic (int [2]) v0; /* { dg-error "array type" } */
|
|
_Atomic (void (void)) v1; /* { dg-error "function type" } */
|
|
_Atomic (_Atomic int) v2; /* { dg-error "applied to a qualified type" } */
|
|
_Atomic (const int) v3; /* { dg-error "applied to a qualified type" } */
|
|
_Atomic (volatile int) v4; /* { dg-error "applied to a qualified type" } */
|
|
_Atomic (int *restrict) v5; /* { dg-error "applied to a qualified type" } */
|
|
|
|
/* _Atomic, used as a qualifier, may not be applied to a function or
|
|
array type. */
|
|
typedef int arraytype[2];
|
|
typedef void functiontype (void);
|
|
_Atomic arraytype v6; /* { dg-error "array type" } */
|
|
_Atomic arraytype *v7; /* { dg-error "array type" } */
|
|
typedef _Atomic arraytype v8; /* { dg-error "array type" } */
|
|
int v9 = sizeof (_Atomic arraytype); /* { dg-error "array type" } */
|
|
void v10 (_Atomic arraytype parm); /* { dg-error "array type" } */
|
|
struct v11 { _Atomic arraytype f; }; /* { dg-error "array type" } */
|
|
_Atomic functiontype v12; /* { dg-error "function type" } */
|
|
_Atomic functiontype *v13; /* { dg-error "function type" } */
|
|
typedef _Atomic functiontype *v14; /* { dg-error "function type" } */
|
|
void v15 (_Atomic functiontype parm); /* { dg-error "function type" } */
|
|
|
|
/* Function parameters, when function types are required to be
|
|
compatible, may not differ in the presence of _Atomic. See
|
|
c11-atomic-1.c for corresponding tests where _Atomic matches. */
|
|
void fc0 (int _Atomic); /* { dg-message "previous declaration" } */
|
|
void fc0 (int); /* { dg-error "conflicting types" } */
|
|
void fc1 (int); /* { dg-message "prototype declaration" } */
|
|
void
|
|
fc1 (x)
|
|
_Atomic int x; /* { dg-error "match prototype" } */
|
|
{
|
|
}
|
|
void
|
|
fc2 (x) /* { dg-message "previous definition" } */
|
|
_Atomic int x;
|
|
{
|
|
}
|
|
void fc2 (int); /* { dg-error "incompatible type" } */
|
|
void fc3 (int); /* { dg-message "prototype declaration" } */
|
|
void
|
|
fc3 (x)
|
|
_Atomic short x; /* { dg-error "match prototype" } */
|
|
{
|
|
}
|
|
void
|
|
fc4 (x) /* { dg-message "previous definition" } */
|
|
_Atomic short x;
|
|
{
|
|
}
|
|
void fc4 (int); /* { dg-error "incompatible type" } */
|
|
|
|
/* Arrays of atomic elements cannot be initialized with string
|
|
literals. */
|
|
_Atomic char si0[] = ""; /* { dg-error "inappropriate type" } */
|
|
_Atomic char si1[] = u8""; /* { dg-error "inappropriate type" } */
|
|
_Atomic signed char si2[] = ""; /* { dg-error "inappropriate type" } */
|
|
_Atomic signed char si3[] = u8""; /* { dg-error "inappropriate type" } */
|
|
_Atomic unsigned char si4[] = ""; /* { dg-error "inappropriate type" } */
|
|
_Atomic unsigned char si5[] = u8""; /* { dg-error "inappropriate type" } */
|
|
_Atomic __WCHAR_TYPE__ si6[] = L""; /* { dg-error "inappropriate type" } */
|
|
_Atomic __CHAR16_TYPE__ si7[] = u""; /* { dg-error "inappropriate type" } */
|
|
_Atomic __CHAR32_TYPE__ si8[] = U""; /* { dg-error "inappropriate type" } */
|
|
|
|
/* Anything that is syntactically a qualifier applied to the (void)
|
|
parameter list results in undefined behavior, which we
|
|
diagnose. */
|
|
void fv (_Atomic void); /* { dg-error "may not be qualified" } */
|