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.
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;
12 # define EXTERN_C extern "C"
14 # define EXTERN_C extern
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)
32 int a
[] = { 1, 2, 3 };
36 // This is suspect but not a clear error.
41 NOIPA
char* nowarn_ptr (void)
49 NOIPA
char* nowarn_cond_ptr (void)
51 // Distilled from a false positive in Glibc dlerror.c.
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
)
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.
85 MEM[(void * *)p_5(D) + 8B] = q.1_26;
92 NOIPA
void nowarn_intptr_t (void)
96 int a
[] = { 1, 2, 3 };
100 // Using an intptr_t is not diagnosed.
105 NOIPA
void nowarn_string_literal (void)
116 NOIPA
void nowarn_extern_array (int x
)
119 /* This is a silly sanity check. */
130 NOIPA
void nowarn_static_array (int x
)
135 static const char sca
[] = "123";
144 static const int sia
[] = { 1, 2, 3 };
153 static const int sia
[] = { 1, 2, 3 };
154 p
= (const int*)memchr (sia
, x
, sizeof sia
);
162 NOIPA
void nowarn_alloca (unsigned n
)
167 p
= (char*)alloca (n
);
174 p
= (int*)alloca (n
* sizeof *p
);
182 p
= (long*)alloca (n
* sizeof *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 };
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. */
207 NOIPA
void* warn_return_local_addr (void)
211 int a
[] = { 1, 2, 3 };
216 /* Unlike the above case, here the pointer is dangling when it's
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
);
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. */
234 NOIPA
void nowarn_scalar_call_ignored (void *vp
)
244 #pragma GCC diagnostic pop
246 NOIPA
void warn_scalar_call (void)
250 int i
; // { dg-message "'i' declared" "note" }
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)
262 int a
[] = { 1, 2, 3 }; // { dg-message "'a' declared" "note" }
265 sink (p
); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "array" }
269 NOIPA
void* warn_array_return (void)
273 int a
[] = { 1, 2, 3 }; // { dg-message "'a' declared" "note" }
277 return p
; // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "array" }
281 NOIPA
void warn_pr63272_c1 (int i
)
287 int k
= i
; // { dg-message "'k' declared" "note" }
291 sink (p
? *p
: 0); // { dg-warning "dangling pointer 'p' to 'k' may be used" }
295 NOIPA
void warn_pr63272_c4 (void)
300 int b
; // { dg-message "'b' declared" "note" }
304 sink (p
); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'b'" "scalar" }
308 NOIPA
void warn_cond_if (int i
, int n
)
313 int a
[] = { 1, 2 }; // { dg-message "'a' declared" "note" }
319 int *b
= (int*)malloc (n
);
324 sink (p
); // { dg-warning "dangling pointer 'p' to 'a' may be used" }
328 NOIPA
void warn_cond_else (int i
, int n
)
333 int *a
= (int*)malloc (n
);
344 sink (p
); // { dg-warning "dangling pointer 'p' to 'b' may be used" }
348 NOIPA
void warn_cond_if_else (int i
)
353 int a
[] = { 1, 2 }; // { dg-message "'a' declared" "note" }
359 int b
[] = { 3, 4 }; // { dg-message "'b' declared" "pr??????" { xfail *-*-* } }
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.
396 NOIPA
void warn_memchr (char c1
, char c2
, char c3
, char c4
)
400 char a
[] = { c1
, c2
, c3
};// { dg-message "'a' declared" "note" }
401 p
= (char*)memchr (a
, c4
, 3);
406 sink (p
); // { dg-warning "using dangling pointer 'p' to 'a'" }
410 NOIPA
void warn_strchr (char c1
, char c2
, char c3
, char c4
)
414 char a
[] = { c1
, c2
, c3
}; // { dg-message "'a' declared" "note" }
415 p
= (char*)strchr (a
, c4
);
420 sink (p
); // { dg-warning "using dangling pointer 'p' to 'a'" }
424 static inline int* return_arg (int *p
)
429 NOIPA
void warn_inline (int i1
, int i2
, int i3
)
433 int a
[] = { i1
, i2
, i3
}; // { dg-message "'a' declared" "note" }
437 sink (p
); // { dg-warning "using \(a \)?dangling pointer \('p' \)?to 'a'" "inline" }