1 /* PR middle-end/10138 - warn for uninitialized arrays passed as const arguments
2 Verify that -Wuninitialized and -Wmaybe-uninitialized trigger (or don't)
3 when passing uninitialized variables by reference to functions declared
4 with or without attribute access and with (or without) const qualified
5 arguments of array, VLA, or pointer types.
6 { dg-do compile }
7 { dg-options "-O2 -Wall -ftrack-macro-expansion=0 -ftrivial-auto-var-init=zero" } */
8
9 #define NONE /* none */
10 #define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
11 #define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
12 #define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
13 #define X(...) __attribute__ ((access (none, __VA_ARGS__)))
14
15 #define CONCAT(x, y) x ## y
16 #define CAT(x, y) CONCAT (x, y)
17 #define UNIQ(pfx) CAT (pfx, __LINE__)
18
19 extern void sink (void*);
20
21
22 #define T1(attr, name, type) \
23 void UNIQ (CAT (test_, name))(void) { \
24 extern attr void UNIQ (name)(type); \
25 int x; \
26 UNIQ (name)(&x); \
27 sink (&x); \
28 }
29
30 #define T2(attr, name, types) \
31 void UNIQ (CAT (test_, name))(void) { \
32 extern attr void UNIQ (name)(types); \
33 int x; \
34 UNIQ (name)(1, &x); \
35 sink (&x); \
36 }
37
38
39 typedef int IA_[];
40 typedef const int CIA_[];
41
42 T1 (NONE, fia_, IA_);
43 T1 (NONE, fcia_, CIA_); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
44 T1 (RO (1), froia_, IA_); // { dg-warning "\\\[-Wuninitialized" "" }
45 T1 (RW (1), frwia_, IA_); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
46 T1 (WO (1), fwoia_, IA_);
47 T1 (X (1), fxia_, IA_);
48
49
50 typedef int IA1[1];
51 typedef const int CIA1[1];
52
53 T1 (NONE, fia1, IA1);
54 T1 (NONE, fcia1, CIA1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
55 T1 (RO (1), froia1, IA1); // { dg-warning "\\\[-Wuninitialized" "" }
56 T1 (RW (1), frwia1, IA1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
57 T1 (WO (1), fwoia1, IA1);
58 T1 (X (1), fxia1, IA1);
59
60
61 #define IARS1 int[restrict static 1]
62 #define CIARS1 const int[restrict static 1]
63
64 T1 (NONE, fiars1, IARS1);
65 T1 (NONE, fciars1, CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" "" }
66 T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" "" }
67 T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
68 T1 (WO (1), fwoiars1, IARS1);
69 T1 (X (1), fxiars1, IARS1);
70
71
72 #define IAS1 int[static 1]
73 #define CIAS1 const int[static 1]
74
75 T1 (NONE, fias1, IAS1);
76 T1 (NONE, fcias1, CIAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
77 T1 (RO (1), froias1, IAS1); // { dg-warning "\\\[-Wuninitialized" "" }
78 T1 (RW (1), frwias1, IAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
79 T1 (WO (1), fwoias1, IAS1);
80 T1 (X (1), fxias1, IAS1);
81
82
83 #define IAX int[*]
84 #define CIAX const int[*]
85
86 T1 (NONE, fiax, IAX);
87 T1 (NONE, fciax, CIAX); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
88 T1 (RO (1), froiax, IAX); // { dg-warning "\\\[-Wuninitialized" "" }
89 T1 (RW (1), frwiax, IAX); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
90 T1 (WO (1), fwoiax, IAX);
91 T1 (X (1), fxiax, IAX);
92
93
94 #define IAN int n, int[n]
95 #define CIAN int n, const int[n]
96
97 T2 (NONE, fian, IAN);
98 T2 (NONE, fcian, CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
99 T2 (RO (2, 1), froian, IAN); // { dg-warning "\\\[-Wuninitialized" "" }
100 T2 (RW (2, 1), frwian, IAN); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
101 T2 (WO (2, 1), fwoian, IAN);
102 T2 (X (2, 1), fxian, IAN);
103
104
105 typedef int* IP;
106 typedef const int* CIP;
107
108 T1 (NONE, fip, IP);
109 T1 (NONE, fcip, CIP); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
110 T1 (RO (1), froip, IP); // { dg-warning "\\\[-Wuninitialized" "" }
111 T1 (RW (1), frwip, IP); // { dg-warning "\\\[-Wmaybe-uninitialized" "" }
112 T1 (WO (1), fwoip, IP);
113 T1 (X (1), fxip, IP);
114
115
116 /* Verify that the notes printed after the warning mention attribute
117 access only when the attribute is explicitly used in the declaration
118 and not otherwise. */
119
120 void test_note_cst_restrict (void)
121 {
122 extern void
123 fccar (const char[restrict]); // { dg-message "by argument 1 of type 'const char\\\[restrict]' to 'fccar'" "note" }
124
125 char a[1]; // { dg-message "'a' declared here" "note" }
126 fccar (a); // { dg-warning "'a' may be used uninitialized" }
127 }
128
129 void test_note_vla (int n)
130 {
131 extern void
132 fccvla (const char[n]); // { dg-message "by argument 1 of type 'const char\\\[n]' to 'fccvla'" "note" }
133
134 char a[2]; // { dg-message "'a' declared here" "note" }
135 fccvla (a); // { dg-warning "'a' may be used uninitialized" }
136 }
137
138 void test_note_ro (void)
139 {
140 extern RO (1) void
141 frocar (char[restrict]); // { dg-message "in a call to 'frocar' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
142
143 char a[3]; // { dg-message "'a' declared here" "note" }
144 frocar (a); // { dg-warning "'a' is used uninitialized" }
145 }
146
147 void test_note_rw (void)
148 {
149 extern RW (1) void
150 frwcar (char[restrict]); // { dg-message "in a call to 'frwcar' declared with attribute 'access \\\(read_write, 1\\\)'" "note" }
151
152 char a[4]; // { dg-message "'a' declared here" "note" }
153 frwcar (a); // { dg-warning "'a' may be used uninitialized" }
154 }