Require target lra in gcc.dg/pr108095.c
[official-gcc.git] / gcc / testsuite / c-c++-common / Wdangling-pointer-2.c
blob20f11b227d647f8db28fc0489591d1ad8c407b83
1 /* PR middle-end/63272 - GCC should warn when using pointer to dead scoped
2 variable within the same function
3 Exercise basic cases of -Wdangling-pointer with optimization.
4 { dg-do compile }
5 { dg-options "-O2 -Wall -Wno-uninitialized -Wno-return-local-addr -ftrack-macro-expansion=0" }
6 { dg-require-effective-target alloca } */
8 typedef __INTPTR_TYPE__ intptr_t;
9 typedef __SIZE_TYPE__ size_t;
11 #if __cplusplus
12 # define EXTERN_C extern "C"
13 #else
14 # define EXTERN_C extern
15 #endif
17 #define NOIPA __attribute__ ((noipa))
19 EXTERN_C void* alloca (size_t);
20 EXTERN_C void* malloc (size_t);
21 EXTERN_C void* memchr (const void*, int, size_t);
22 EXTERN_C char* strchr (const char*, int);
24 int sink (const void*, ...);
25 #define sink(...) sink (0, __VA_ARGS__)
28 NOIPA void nowarn_addr (void)
30 int *p;
32 int a[] = { 1, 2, 3 };
33 p = a;
36 // This is suspect but not a clear error.
37 sink (&p);
41 NOIPA char* nowarn_ptr (void)
43 char *p;
44 sink (&p);
45 return p;
49 NOIPA char* nowarn_cond_ptr (void)
51 // Distilled from a false positive in Glibc dlerror.c.
52 char *q;
53 if (sink (&q))
54 return q;
56 return 0;
60 NOIPA void nowarn_loop_ptr (int n, int *p)
62 // Distilled from a false positive in Glibc td_thr_get_info.c.
63 for (int i = 0; i != 2; ++i)
65 int x;
66 sink (&x);
67 *p++ = x;
70 /* With the loop unrolled, Q is clobbered just before the call to
71 sink(), making it indistinguishable from passing it a pointer
72 to an out-of-scope variable. Verify that the warning doesn't
73 suffer from false positives due to this.
74 int * q;
75 int * q.1_17;
76 int * q.1_26;
78 <bb 2>:
79 f (&q);
80 q.1_17 = q;
81 *p_5(D) = q.1_17;
82 q ={v} {CLOBBER};
83 f (&q);
84 q.1_26 = q;
85 MEM[(void * *)p_5(D) + 8B] = q.1_26;
86 q ={v} {CLOBBER};
87 return;
92 NOIPA void nowarn_intptr_t (void)
94 intptr_t ip;
96 int a[] = { 1, 2, 3 };
97 ip = (intptr_t)a;
100 // Using an intptr_t is not diagnosed.
101 sink (0, ip);
105 NOIPA void nowarn_string_literal (void)
107 const char *s;
109 s = "123";
112 sink (s);
116 NOIPA void nowarn_extern_array (int x)
119 /* This is a silly sanity check. */
120 extern int eia[];
121 int *p;
123 p = eia;
125 sink (p);
130 NOIPA void nowarn_static_array (int x)
133 const char *s;
135 static const char sca[] = "123";
136 s = sca;
139 sink (s);
142 const int *p;
144 static const int sia[] = { 1, 2, 3 };
145 p = sia;
148 sink (p);
151 const int *p;
153 static const int sia[] = { 1, 2, 3 };
154 p = (const int*)memchr (sia, x, sizeof sia);
157 sink (p);
162 NOIPA void nowarn_alloca (unsigned n)
165 char *p;
167 p = (char*)alloca (n);
169 sink (p);
172 int *p;
174 p = (int*)alloca (n * sizeof *p);
175 sink (p);
177 sink (p);
180 long *p;
182 p = (long*)alloca (n * sizeof *p);
183 sink (p);
184 p = p + 1;
186 sink (p);
191 #pragma GCC diagnostic push
192 /* Verify that -Wdangling-pointer works with #pragma diagnostic. */
193 #pragma GCC diagnostic ignored "-Wdangling-pointer"
196 NOIPA void* nowarn_return_local_addr (void)
198 int a[] = { 1, 2, 3 };
199 int *p = a;
201 /* This is a likely bug but it's not really one of using a dangling
202 pointer but rather of returning the address of a local variable
203 which is diagnosed by -Wreturn-local-addr. */
204 return p;
207 NOIPA void* warn_return_local_addr (void)
209 int *p = 0;
211 int a[] = { 1, 2, 3 };
212 sink (a);
213 p = a;
216 /* Unlike the above case, here the pointer is dangling when it's
217 used. */
218 return p; // { dg-warning "using dangling pointer 'p' to 'a'" "pr??????" { xfail *-*-* } }
222 NOIPA void* nowarn_return_alloca (int n)
224 int *p = (int*)alloca (n);
225 sink (p);
227 /* This is a likely bug but it's not really one of using a dangling
228 pointer but rather of returning the address of a local variable
229 which is diagnosed by -Wreturn-local-addr. */
230 return p;
234 NOIPA void nowarn_scalar_call_ignored (void *vp)
236 int *p;
238 int i;
239 p = &i;
241 sink (p);
244 #pragma GCC diagnostic pop
246 NOIPA void warn_scalar_call (void)
248 int *p;
250 int i; // { dg-message "'i' declared" "note" }
251 p = &i;
253 // When the 'p' is optimized away it's not mentioned in the warning.
254 sink (p); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'i'" "array" }
258 NOIPA void warn_array_call (void)
260 int *p;
262 int a[] = { 1, 2, 3 }; // { dg-message "'a' declared" "note" }
263 p = a;
265 sink (p); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "array" }
269 NOIPA void* warn_array_return (void)
271 int *p;
273 int a[] = { 1, 2, 3 }; // { dg-message "'a' declared" "note" }
274 p = a;
277 return p; // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "array" }
281 NOIPA void warn_pr63272_c1 (int i)
283 int *p = 0;
285 if (i)
287 int k = i; // { dg-message "'k' declared" "note" }
288 p = &k;
291 sink (p ? *p : 0); // { dg-warning "dangling pointer 'p' to 'k' may be used" }
295 NOIPA void warn_pr63272_c4 (void)
297 int *p = 0;
300 int b; // { dg-message "'b' declared" "note" }
301 p = &b;
304 sink (p); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'b'" "scalar" }
308 NOIPA void warn_cond_if (int i, int n)
310 int *p;
311 if (i)
313 int a[] = { 1, 2 }; // { dg-message "'a' declared" "note" }
314 sink (a);
315 p = a;
317 else
319 int *b = (int*)malloc (n);
320 sink (b);
321 p = b;
324 sink (p); // { dg-warning "dangling pointer 'p' to 'a' may be used" }
328 NOIPA void warn_cond_else (int i, int n)
330 int *p;
331 if (i)
333 int *a = (int*)malloc (n);
334 sink (a);
335 p = a;
337 else
339 int b[] = { 2, 3 };
340 sink (b);
341 p = b;
344 sink (p); // { dg-warning "dangling pointer 'p' to 'b' may be used" }
348 NOIPA void warn_cond_if_else (int i)
350 int *p;
351 if (i)
353 int a[] = { 1, 2 }; // { dg-message "'a' declared" "note" }
354 sink (a);
355 p = a;
357 else
359 int b[] = { 3, 4 }; // { dg-message "'b' declared" "pr??????" { xfail *-*-* } }
360 sink (b);
361 p = b;
364 /* With a PHI with more than invalid argument, only one use is diagnosed
365 because after the first diagnostic the code suppresses subsequent
366 ones for the same use. This needs to be fixed. */
367 sink (p); // { dg-warning "dangling pointer 'p' to 'a' may be used" }
368 // { dg-warning "dangling pointer 'p' to 'b' may be used" "pr??????" { xfail *-*-* } .-1 }
372 NOIPA void nowarn_gcc_i386 (int i)
374 // Regression test reduced from gcc's i386.c.
375 char a[32], *p;
377 if (i != 1)
378 p = a;
379 else
380 p = 0;
382 if (i == 2)
383 sink (p);
384 else
386 if (p)
388 sink (p);
389 return;
391 sink (p);
396 NOIPA void warn_memchr (char c1, char c2, char c3, char c4)
398 char *p = 0;
400 char a[] = { c1, c2, c3 };// { dg-message "'a' declared" "note" }
401 p = (char*)memchr (a, c4, 3);
402 if (!p)
403 return;
406 sink (p); // { dg-warning "using dangling pointer 'p' to 'a'" }
410 NOIPA void warn_strchr (char c1, char c2, char c3, char c4)
412 char *p = 0;
414 char a[] = { c1, c2, c3 }; // { dg-message "'a' declared" "note" }
415 p = (char*)strchr (a, c4);
416 if (!p)
417 return;
420 sink (p); // { dg-warning "using dangling pointer 'p' to 'a'" }
424 static inline int* return_arg (int *p)
426 return p;
429 NOIPA void warn_inline (int i1, int i2, int i3)
431 int *p;
433 int a[] = { i1, i2, i3 }; // { dg-message "'a' declared" "note" }
434 p = return_arg (a);
437 sink (p); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "inline" }