1 /* PR c/50584 - No warning for passing small array to C99 static array
2 declarator
3 Verify that -Warray-parameter diagnoses mismatches in array (and
4 pointer) arrguments between redeclarations of the same function.
5 Also verify that the array/pointer argument form in a mismatched
6 redeclaration doesn't override the form in the initial declaration.
7 { dg-do compile }
8 { dg-options "-Wall -Warray-parameter -Wno-vla-parameter" } */
9
10 /* Redclarations with the same or equivalent array form should not
11 be dianosed. T[0] is diagnosed by -Wpedantic for being invalid
12 C so there's little point in also warning for the difference in
13 array form. */
14 void f1vpp (void**);
15 void f1vpp (void*[]);
16 void f1vpp (void*[0]);
17
18 void f1ia_ (int[]);
19 void f1ia_ (int[]);
20 void f1ia_ (int[0]);
21 /* Verify the unused attribute still has an effect. */
22 void f1ia_ (int a[0] __attribute__ ((unused))) { }
23 void f1ia_ (int[]);
24
25 void f1ia_p (int[]);
26 void f1ia_p (int*);
27 void f1ia_p (int *p __attribute__ ((unused))) { }
28 void f1ia_p (int[]);
29
30 void f1p_ia (const int*);
31 void f1p_ia (const int[]);
32 void f1p_ia (const int *p __attribute__ ((unused))) { }
33 void f1p_ia (const int[]);
34
35 void f1ia1 (int[1]);
36 void f1ia1 (int[1]);
37 void f1ia1 (int[2 - 1]);
38
39 void f1ias2 (int[static 2]);
40 void f1ias2 (int[static 2]);
41 void f1ias2 (int[static 1 + 1]);
42 void f1ias2 (int a[static 3 - 1]) { (void)&a; }
43
44 void f1ipa_ (int*[]);
45 void f1ipa_ (int*[]);
46 void f1ipa_ (int*[0]);
47
48 void f1ia1_x (int[1]); // { dg-message "previously declared as 'int\\\[1]'" }
49 void f1ia1_x (int[]); // { dg-warning "argument 1 of type 'int\\\[]' with mismatched bound" }
50 void f1ia1_x (int[]); // { dg-warning "argument 1 of type 'int\\\[]' with mismatched bound" }
51 void f1ia1_x (int[1]);
52 void f1ia1_x (int[2]); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
53 void f1ia1_x (int[1]);
54 void f1ia1_x (int[3]); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
55 void f1ia1_x (int a[1] __attribute__ ((unused))) { }
56
57
58 void f1ias2_s3 (int[static 2]); // { dg-message "previously declared as 'int\\\[static 2]'" }
59 void f1ias2_s3 (int[static 3]); // { dg-warning "argument 1 of type 'int\\\[static 3]' with mismatched bound" }
60 /* Verify the unused attribute still has an effect and doesn't interfere
61 with the warning. */
62 void f1ias2_s3 (int a[static 3] __attribute__ ((unused))) { } // { dg-warning "argument 1 of type 'int\\\[static 3]' with mismatched bound" }
63
64
65 /* Ordinary T[N] and T[static N] forms are both effectively treated
66 the same but strictly have different meanings so they are diagnosed.
67 It might be worth splitting the warning into two levels and having
68 only the higher level treat the ordinary form as T[static N]. */
69
70 void f1ia3_s4 (int[3]); // { dg-message "previously declared as 'int\\\[3]'" }
71 void f1ia3_s4 (int[static 4]); // { dg-warning "argument 1 of type 'int\\\[static 4]' with mismatched bound" }
72 void f1ia3_s4 (int[3]);
73
74
75 void f1ias4_5 (int[static 4]); // { dg-message "previously declared as 'int\\\[static 4]'" }
76 void f1ias4_5 (int[5]); // { dg-warning "argument 1 of type 'int\\\[5]' with mismatched bound" }
77 void f1ias4_5 (int[static 4]);
78
79
80 void f1ia_1 (int[]); // { dg-message "previously declared as 'int\\\[]'" }
81 void f1ia_1 (int[1]); // { dg-warning "argument 1 of type 'int\\\[1]' with mismatched bound" }
82 void f1ia_1 (int[]);
83
84
85 void f1ca_ (char[]); // { dg-message "previously declared as 'char\\\[]'" }
86 void f1ca_ (char[2]); // { dg-warning "argument 1 of type 'char\\\[2]' with mismatched bound" }
87 void f1ca_ (char[]);
88
89
90 void f1csp (const short*); // { dg-message "previously declared as 'const short int ?\\\*'" }
91 void f1csp (const short[3]); // { dg-warning "argument 1 of type 'const short int\\\[3]' with mismatched bound" }
92 void f1csp (const short*);
93
94
95 void f1ia2 (int[2]); // { dg-message "previously declared as 'int\\\[2]'" }
96 void f1ia2 (int[1]); // { dg-warning "argument 1 of type 'int\\\[1]' with mismatched bound" }
97 void f1ia2 (int[2]);
98
99
100 void f1cvla2 (const volatile long[3]); // { dg-message "previously declared as 'const volatile long int\\\[3]'" }
101 void f1cvla2 (const volatile long[2]); // { dg-warning "argument 1 of type 'const volatile long int\\\[2]' with mismatched bound" }
102 void f1cvla2 (const volatile long[3]);
103 void f1cvla2 (const volatile long[restrict 4]); // { dg-warning "argument 1 of type 'const volatile long int\\\[restrict 4]' with mismatched bound" }
104
105
106 void f1afa4 (_Atomic float[3]); // { dg-message "previously declared as an array '_Atomic float ?\\\[3]'" }
107 void f1afa4 (_Atomic float*); // { dg-warning "argument 1 of type '_Atomic float ?\\\*' declared as a pointer" }
108 void f1afa4 (_Atomic float[3]);
109
110 void f1ipa1_a2 (int*[1]); // { dg-message "previously declared as 'int \\\*\\\[1]'" }
111 void f1ipa1_a2 (int*[2]); // { dg-warning "argument 1 of type 'int \\\*\\\[2]' with mismatched bound" }
112 void f1ipa1_a2 (int*[1]);
113
114
115 typedef int IAx[];
116 typedef int IA1[1];
117 typedef int IA2[2];
118 typedef int IA3[3];
119
120 // The message should differentiate between the [] form and *.
121 void f1IAx_A1 (IAx); // { dg-message "previously declared as 'int\\\[]'" "pr?????" { xfail *-*-* } }
122 // { dg-message "previously declared as 'int *\\\*'" "note" { target *-*-* } .-1 }
123 void f1IAx_A1 (IA1); // { dg-message "argument 1 of type 'int\\\[1]' with mismatched bound" }
124
125 void f1IA1_A2 (IA1); // { dg-message "previously declared as 'int\\\[1]'" }
126 void f1IA1_A2 (IA2); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
127 void f1IA1_A2 (IA1);
128 void f1IA1_A2 (int[2]); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
129
130
131 void f1IA1_A3 (IA1 ia1); // { dg-message "previously declared as 'int\\\[1]'" }
132 void f1IA1_A3 (IA3 ia3); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
133 void f1IA1_A3 (IA1 ia1);
134
135
136 void f1IA2_A3 (IA2 a); // { dg-message "previously declared as 'int\\\[2]'" }
137 void f1IA2_A3 (IA3 a); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
138 void f1IA2_A3 (IA2 a);
139
140
141 // Verify multiple array arguments.
142
143 void f2a2_a3_3_3 (int[2], int[3]); // { dg-message "previously declared as 'int\\\[2]'" }
144 void f2a2_a3_3_3 (int[2], int[3]);
145 void f2a2_a3_3_3 (int[3], int[3]); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
146
147
148 void f2a2_a3_2_4 (int[2], int[3]); // { dg-message "previously declared as 'int\\\[3]'" }
149 void f2a2_a3_2_4 (int[2], int[4]); // { dg-warning "argument 2 of type 'int\\\[4]' with mismatched bound" }
150
151
152 /* Verify that pointers to arrays and arrays of arrays are differentiated
153 the same way as pointers and arrays of other types. */
154 typedef IA1 *PA1;
155
156 void fpia1 (IA1*); // { dg-message "previously declared as 'int ?\\(\\\*\\)\\\[1]'" }
157 void fpia1 (IA1[1]); // { dg-warning "argument 1 of type 'int\\\[1]\\\[1]' with mismatched bound" }
158 void fpia1 (PA1);
159 void fpia1 (int(*)[1]);
160 void fpia1 (int[][1]);
161
162 void f1vpa1 (void*[][1]);
163 void f1vpa1 (void*[0][1]);
164
165 /* Verify arrays of pointers. */
166 void vaip1 (int (*[3])); // { dg-message "previously declared as 'int *\\\*\\\[3]'" }
167 void vaip1 (int (*[5])); // { dg-warning "argument 1 of type 'int *\\\*\\\[5]' with mismatched bound" }
168 void vaip1 (int (*[3]));
169 void vaip1 (int (*[])); // { dg-warning "argument 1 of type 'int *\\\*\\\[]' with mismatched bound" }
170 void vaip1 (int (*[3]));
171
172 /* Verify that attributes with arrays don't cause unwanted warnings and
173 don't suppress intended ones. */
174
175 #define ALIGN(N)__attribute__ ((aligned (__alignof__ (char[N]))))
176
177 void fatipa2 (int (* ALIGN (3)[2])); // { dg-message "previously declared as 'int \\\*\\\[2]'" }
178 void fatipa2 (int (* ALIGN (4)[2]));
179 void fatipa2 (int (* ALIGN (5)[2]));
180 void fatipa2 (int (* ALIGN (7)[3])); // { dg-warning "argument 1 of type 'int \\\*\\\[3]' with mismatched bound" }
181
182 void fatiap (int (* ALIGN (3))[2]);
183 void fatiap (int (* ALIGN (5))[2]);
184
185
186 void fatipa3 (int (* ALIGN (1) (* ALIGN (2))[3]));
187 void fatipa3 (int (* ALIGN (1) (* ALIGN (2))[3]));