1/*	$NetBSD: c11.c,v 1.7 2024/05/07 19:32:35 rillig Exp $	*/
2# 3 "c11.c"
3
4/*
5 * Test the language level C11, which adds _Generic expressions, _Noreturn
6 * functions, anonymous struct/union members, and several more.
7 */
8
9/* lint1-flags: -Ac11 -w -X 192,231,236,351 */
10
11
12int
13bool_is_predefined_in_c23(void)
14{
15	/* expect+1: error: syntax error 't' [249] */
16	bool t = true;
17	bool f = false;
18	/* expect+4: error: 't' undefined [99] */
19	/* expect+3: error: 'true' undefined [99] */
20	/* expect+2: error: 'f' undefined [99] */
21	/* expect+1: error: 'false' undefined [99] */
22	return (t == true ? 20 : 0) + (f == false ? 3 : 0);
23}
24
25int
26c99_bool_is_still_valid_in_c23(void)
27{
28	_Bool t = 1;
29	_Bool f = 0;
30	return (t == 1 ? 20 : 0) + (f == 0 ? 3 : 0);
31}
32
33
34_Noreturn void exit(int);
35void _Noreturn exit(int);
36
37_Noreturn void
38noreturn_before_type(void)
39{
40	exit(0);
41}
42
43void _Noreturn
44noreturn_after_type(void)
45{
46	exit(0);
47}
48
49static _Noreturn void
50noreturn_after_storage_class(void)
51{
52	exit(0);
53}
54
55_Noreturn static void
56noreturn_before_storage_class(void)
57{
58	exit(0);
59}
60
61/* C11 6.7.4p5: A function specifier may appear more than once. */
62_Noreturn _Noreturn _Noreturn void
63three_times(void)
64{
65	exit(0);
66}
67
68
69struct static_assert_tag {
70	_Static_assert(1 > 0, "string");
71	int member;
72};
73
74
75// C11 6.7.6.1p3
76const int *ptr_to_constant;
77int *const constant_ptr;
78
79// C11 6.7.6.1p4
80typedef int *int_ptr;
81const int_ptr constant_ptr;
82
83// C11 6.7.6.2p7
84float fa[11], *afp[17];
85
86// C11 6.7.6.2p8
87extern int *x;
88extern int y[];
89
90// C11 6.7.6.2p9
91extern int n;
92extern int m;
93void fcompat(void)
94{
95	int a[n][6][m];
96	int (*p)[4][n+1];
97	int c[n][n][6][m];
98	int (*r)[n][n][n+1];
99	/* expect+1: warning: illegal combination of 'pointer to array[4] of array[1] of int' and 'pointer to array[6] of array[1] of int', op '=' [124] */
100	p = a;
101	/* expect+1: warning: illegal combination of 'pointer to array[1] of array[1] of array[1] of int' and 'pointer to array[1] of array[6] of array[1] of int', op '=' [124] */
102	r = c;
103}
104
105// C11 6.7.6.2p10
106extern int n;
107int A[n];
108extern int (*p2)[n];
109int B[100];
110void fvla(int m, int C[m][m]);
111void fvla(int m, int C[m][m])
112{
113	typedef int VLA[m][m];
114	struct tag {
115		int (*y)[n];
116		int z[n];
117	};
118	int D[m];
119	static int E[m];
120	/* expect+1: warning: nested 'extern' declaration of 'F' [352] */
121	extern int F[m];
122	int (*s)[m];
123	/* expect+1: warning: nested 'extern' declaration of 'r' [352] */
124	extern int (*r)[m];
125	/* expect+1: warning: illegal combination of 'pointer to array[1] of int' and 'pointer to int', op 'init' [124] */
126	static int (*q)[m] = &B;
127}
128
129// C11 6.7.6.3p15
130int f(void), *fip(), (*pfi)();
131
132// C11 6.7.6.3p17
133int (*apfi[3])(int *x, int *y);
134
135// C11 6.7.6.3p18
136int (*fpfi(int (*)(long), int))(int, ...);
137
138// C11 6.7.6.3p19
139void addscalar(int n, int m, double a[n][n*m+300], double x);
140int main(void)
141{
142	double b[4][308];
143	/* expect+1: warning: converting 'pointer to array[308] of double' to incompatible 'pointer to array[1] of double' for argument 3 [153] */
144	addscalar(4, 2, b, 2.17);
145	return 0;
146}
147void addscalar(int n, int m, double a[n][n*m+300], double x)
148{
149	for (int i = 0; i < n; i++)
150		for (int j = 0, k = n*m+300; j < k; j++)
151			a[i][j] += x;
152}
153
154// C11 6.7.6.3p20
155double maximum(int n, int m, double a[n][m]);
156/* expect+1: error: null dimension [17] */
157double maximum(int n, int m, double a[*][*]);
158/* expect+1: error: null dimension [17] */
159double maximum(int n, int m, double a[ ][*]);
160double maximum(int n, int m, double a[ ][m]);
161
162void f1(double (* restrict a)[5]);
163void f2(double a[restrict][5]);
164/* expect+1: error: syntax error '3' [249] */
165void f3(double a[restrict 3][5]);
166void f4(double a[restrict static 3][5]);
167
168
169// In C11 mode, 'thread_local' is not yet known, but '_Thread_local' is.
170/* expect+2: error: old-style declaration; add 'int' [1] */
171/* expect+1: error: syntax error 'int' [249] */
172thread_local int thread_local_variable_c23;
173_Thread_local int thread_local_variable_c11;
174
175/* The '_Noreturn' must not appear after the declarator. */
176/* expect+2: error: formal parameter #1 lacks name [59] */
177/* expect+1: warning: empty declaration [2] */
178void _Noreturn exit(int) _Noreturn;
179/* expect+2: error: syntax error '' [249] */
180/* expect+1: error: cannot recover from previous errors [224] */
181