1 /* Verify that accessing freed objects by built-in functions is diagnosed.
3 { dg-options "-Wall" } */
5 typedef __SIZE_TYPE__
size_t;
8 # define EXTERN_C extern "C"
10 # define EXTERN_C extern
13 EXTERN_C
void free (void*);
14 EXTERN_C
void* realloc (void*, size_t);
16 EXTERN_C
void* memcpy (void*, const void*, size_t);
17 EXTERN_C
char* strcpy (char*, const char*);
18 EXTERN_C
size_t strlen (const char*);
21 void sink (void*, ...);
23 struct Member
{ char *p
; char a
[4]; };
25 int nowarn_strcpy_memptr (struct Member
*p
)
27 char *q
= strcpy (p
->p
, p
->a
);
32 int nowarn_strlen_memptr (struct Member
*p
)
41 int warn_strlen_memptr (struct Member
*p
)
43 free (p
); // { dg-message "call to '\(void \)?free\(\\(void\\*\\)\)?'" "note" }
44 return strlen (p
->p
); // { dg-warning "-Wuse-after-free" }
47 int warn_strlen_memarray (struct Member
*p
)
51 return strlen (p
->a
); // { dg-warning "-Wuse-after-free" }
58 return strlen (q
); // { dg-warning "-Wuse-after-free" "pr??????" { xfail *-*-* } }
62 void* nowarn_realloc_success (void *p
)
64 void *q
= realloc (p
, 7);
66 /* When realloc fails the original pointer remains valid. */
72 void* nowarn_realloc_equal (void *p
, int *moved
)
74 void *q
= realloc (p
, 7);
75 /* Verify that equality is not diagnosed at the default level
76 (it is diagnosed at level 3). */
81 void* nowarn_realloc_unequal (void *p
, int *moved
)
83 void *q
= realloc (p
, 7);
84 /* Verify that inequality is not diagnosed at the default level
85 (it is diagnosed at level 3). */
90 void* warn_realloc_relational (void *p
, int *rel
)
92 void *q
= realloc (p
, 7); // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
93 /* Verify that all relational expressions are diagnosed at the default
95 rel
[0] = (char*)p
< (char*)q
; // { dg-warning "-Wuse-after-free" }
96 rel
[1] = (char*)p
<= (char*)q
; // { dg-warning "-Wuse-after-free" }
97 rel
[2] = (char*)p
>= (char*)q
; // { dg-warning "-Wuse-after-free" }
98 rel
[3] = (char*)p
> (char*)q
; // { dg-warning "-Wuse-after-free" }
102 void* warn_realloc_unchecked (void *p
, int *moved
)
104 void *q
= realloc (p
, 7); // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
105 /* Use subtraction rather than inequality to trigger the warning
106 at the default level (equality is diagnosed only at level 3). */
107 *moved
= (char*)p
- (char*)q
; // { dg-warning "-Wuse-after-free" }
111 void* nowarn_realloc_unchecked_copy (void *p1
, void *p2
, const void *s
,
114 void *p3
= memcpy (p1
, s
, n
);
115 void *p4
= realloc (p2
, 7);
120 void* warn_realloc_unchecked_copy (void *p
, const void *s
, int n
, int *moved
)
122 void *p2
= memcpy (p
, s
, n
);
123 void *q
= realloc (p
, 7); // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
124 *moved
= (char*)p2
- (char*)q
; // { dg-warning "-Wuse-after-free" }
128 void* warn_realloc_failed (void *p
, int *moved
)
130 void *q
= realloc (p
, 7); // { dg-message "call to '\(void\\* \)?realloc\(\\(void\\*, size_t\\)\)?'" "note" }
133 /* When realloc succeeds the original pointer is invalid. */
134 *moved
= (char*)p
- (char*)q
; // { dg-warning "-Wuse-after-free" }
143 void* warn_realloc_extern (void *p
, int *moved
)
145 evp
= realloc (p
, 7);
148 /* When realloc succeeds the original pointer is invalid. */
149 *moved
= (char*)p
- (char*)evp
; // { dg-warning "-Wuse-after-free" "escaped" }
153 return p
; // { dg-bogus "-Wuse-after-free" "safe use after realloc failure" { xfail *-*-* } }
156 struct A
{ void *p
, *q
; int moved
; };
158 void* warn_realloc_arg (struct A
*p
)
160 p
->q
= realloc (p
->p
, 7);
163 /* When realloc succeeds the original pointer is invalid. */
164 p
->moved
= p
->p
!= p
->q
; // { dg-warning "-Wuse-after-free" "escaped" { xfail *-*-* } }