--- /dev/null
+/* Test qualified function types: implementation-defined in C2y, undefined
+ behavior previously. GCC has an extension here, but does not allow it in
+ pedantic mode. _Atomic and restrict are constraint violations here. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+typedef void FUNC (void);
+
+const FUNC f1; /* { dg-error "ISO C forbids qualified function types" } */
+volatile FUNC f2; /* { dg-error "ISO C forbids qualified function types" } */
+restrict FUNC f3; /* { dg-error "ISO C forbids qualified function types" } */
+/* { dg-error "invalid use of 'restrict'" "restrict" { target *-*-* } .-1 } */
+_Atomic FUNC f4; /* { dg-error "'_Atomic'-qualified function type" } */
--- /dev/null
+/* Test C2y constraint for incomplete types of objects with no linkage. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+struct s1;
+
+void
+f ()
+{
+ struct s1 a; /* { dg-error "storage size" } */
+ int b[]; /* { dg-error "array size missing" } */
+ static struct s1 c; /* { dg-error "storage size" } */
+ static int d[]; /* { dg-error "array size missing" } */
+ struct s2;
+ struct s2 e; /* { dg-error "storage size" } */
+ static struct s2 g; /* { dg-error "storage size" } */
+ struct s2 { int i; };
+}
+
+struct s1 { int j; };
--- /dev/null
+/* Test C2y constraint that inline functions with external linkage must be
+ defined in same translation unit. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+inline void f (); /* { dg-error "declared but never defined" } */
+extern inline void g(); /* { dg-error "declared but never defined" } */
--- /dev/null
+/* Test C2y constraints on pointer conversions. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+#include <stddef.h>
+#include <stdint.h>
+
+void *p1;
+struct s { int a; } s1;
+struct sp { void *p; } s2;
+union t { int b; } t1;
+union tp { void *p; } t2;
+
+void
+f ()
+{
+ (double) p1; /* { dg-error "pointer value used where a floating-point was expected" } */
+ (struct s) p1; /* { dg-error "conversion to non-scalar type requested" } */
+ (union t) p1; /* { dg-error "cast to union type from type not present in union" } */
+ (struct sp) p1; /* { dg-error "conversion to non-scalar type requested" } */
+ (union tp) p1; /* { dg-error "ISO C forbids casts to union type" } */
+ (nullptr_t) p1; /* { dg-error "conversion" } */
+ /* { dg-message "or a null pointer constant can be converted" "conversion note" { target *-*-* } .-1 } */
+ (intptr_t) p1;
+ (int *) p1;
+ (void) p1;
+ (void *) 0.0; /* { dg-error "cannot convert to a pointer type" } */
+ (void *) s1; /* { dg-error "cannot convert to a pointer type" } */
+ (void *) t1; /* { dg-error "cannot convert to a pointer type" } */
+ (void *) s2; /* { dg-error "cannot convert to a pointer type" } */
+ (void *) t2; /* { dg-error "cannot convert to a pointer type" } */
+ (void *) nullptr;
+ (void *) 0;
+ (void *) (int *) 0;
+ (void *) (void) p1; /* { dg-error "invalid use of void expression" } */
+}
+
+void
+g ()
+{
+ double d = p1; /* { dg-error "incompatible types" } */
+ s1 = p1; /* { dg-error "incompatible types" } */
+ t1 = p1; /* { dg-error "incompatible types" } */
+ s2 = p1; /* { dg-error "incompatible types" } */
+ t2 = p1; /* { dg-error "incompatible types" } */
+ nullptr_t np = p1; /* { dg-error "incompatible types" } */
+ p1 = 0.0; /* { dg-error "incompatible types" } */
+ p1 = s1; /* { dg-error "incompatible types" } */
+ p1 = t1; /* { dg-error "incompatible types" } */
+ p1 = s2; /* { dg-error "incompatible types" } */
+ p1 = t2; /* { dg-error "incompatible types" } */
+ p1 = (void) p1; /* { dg-error "invalid use of void expression" } */
+}
--- /dev/null
+/* Test implicit conversion of register arrays to pointers:
+ implementation-defined in C2y, undefined behavior previously. GCC disallows
+ this conversion (the case of array element access changed in C2y no longer
+ to involve the implicit conversion to a pointer). */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+void
+f ()
+{
+ register int a[1];
+ constexpr register int b[1] = { 1 };
+ a; /* { dg-error "address of register variable" } */
+ b; /* { dg-error "address of register variable" } */
+ (void) a; /* { dg-error "address of register variable" } */
+ (void) b; /* { dg-error "address of register variable" } */
+ *a; /* { dg-error "address of register variable" } */
+ *b; /* { dg-error "address of register variable" } */
+ a + 0; /* { dg-error "address of register variable" } */
+ b + 0; /* { dg-error "address of register variable" } */
+}
--- /dev/null
+/* Test C2y constraint on storage-class specifiers for block-scope identifiers
+ for functions. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+void
+f ()
+{
+ auto void g1 (); /* { dg-error "invalid storage class for function" } */
+ /* { dg-error "nested function" "nested" { target *-*-* } .-1 } */
+ constexpr void g2 (); /* { dg-error "requires an initialized data declaration" } */
+ extern void g3 ();
+ register void g4 (); /* { dg-error "invalid storage class for function" } */
+ static void g5 (); /* { dg-error "invalid storage class for function" } */
+ thread_local void g6 (); /* { dg-error "implicitly auto and declared" } */
+ static thread_local void g7 (); /* { dg-error "invalid storage class for function" } */
+ /* { dg-error "nested function" "nested" { target *-*-* } .-1 } */
+}
--- /dev/null
+/* Test structures and unions without named members: implementation-defined in
+ C2y, undefined behavior previously. GCC has an extension here, but does not
+ allow it in pedantic mode. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+struct s1 { }; /* { dg-error "struct has no members" } */
+union u1 { }; /* { dg-error "union has no members" } */
+struct s2 { struct { }; }; /* { dg-error "struct has no members" } */
+struct s3 { int : 3; int : 4; }; /* { dg-error "struct has no named members" } */