118 lines
2.5 KiB
C
118 lines
2.5 KiB
C
/* PR middle-end/104232 - spurious -Wuse-after-free after conditional free
|
|
{ dg-do compile }
|
|
{ dg-options "-O2 -Wall -fno-tree-loop-distribute-patterns" } */
|
|
|
|
void free (void*);
|
|
|
|
void sink (void*);
|
|
|
|
void nowarn_cond_2 (char *p0, char *q0, int i)
|
|
{
|
|
char *r = i ? p0 : q0;
|
|
|
|
free (p0);
|
|
|
|
/* The use of a PHI operand could be diagnosed using the "maybe" form
|
|
of the warning at level 2 but it's not done. If it ever changes
|
|
this test and those below will need to be updated. */
|
|
sink (r);
|
|
}
|
|
|
|
void nowarn_cond_2_null (char *p0, int i)
|
|
{
|
|
char *r = i ? p0 : 0;
|
|
|
|
free (p0);
|
|
sink (r);
|
|
}
|
|
|
|
void nowarn_cond_3 (char *p0, char *q0, int i)
|
|
{
|
|
char *r = i < 0 ? p0 - 1 : 0 < i ? p0 + 1 : q0;
|
|
|
|
free (p0);
|
|
sink (r);
|
|
}
|
|
|
|
void nowarn_cond_3_null (char *p0, int i)
|
|
{
|
|
char *r = i < 0 ? p0 - 1 : 0 < i ? p0 + 1 : 0;
|
|
|
|
free (p0);
|
|
sink (r);
|
|
}
|
|
|
|
void nowarn_cond_4 (char *p0, char *q0, int i)
|
|
{
|
|
char *r = i < -1 ? p0 - 2 : i < 0 ? p0 - 1 : 1 < i ? p0 + 1 : q0;
|
|
|
|
free (p0);
|
|
sink (r);
|
|
}
|
|
|
|
int nowarn_cond_loop (char *p)
|
|
{
|
|
char *q = p;
|
|
while (*q)
|
|
{
|
|
if (*q == 'x')
|
|
{
|
|
q = "";
|
|
break;
|
|
}
|
|
++q;
|
|
}
|
|
|
|
free (p);
|
|
return *q;
|
|
}
|
|
|
|
|
|
void warn_cond_2_cst (char *p, int i)
|
|
{
|
|
/* Same as nowarn_cond_2() above but with R being derived only from
|
|
P, which means that any R's use after P has been freed should be
|
|
diagnosed. */
|
|
char *r = i ? p + 1 : p + 2;
|
|
|
|
free (p); // { dg-message "call to 'free'" }
|
|
sink (r); // { dg-warning "pointer used after 'free'" }
|
|
}
|
|
|
|
void warn_cond_2_var (char *p, int i, int j)
|
|
{
|
|
char *r = i ? p + i : p + j;
|
|
|
|
free (p); // { dg-message "call to 'free'" }
|
|
sink (r); // { dg-warning "pointer used after 'free'" }
|
|
}
|
|
|
|
void warn_cond_3_var (char *p0, int i, int j)
|
|
{
|
|
char *r = i < 0 ? p0 - i : 0 < i ? p0 + j : p0 + i + j;
|
|
|
|
free (p0); // { dg-message "call to 'free'" }
|
|
sink (r + 1); // { dg-warning "pointer used after 'free'" }
|
|
}
|
|
|
|
int warn_cond_4 (char *p0, char *q0, int i)
|
|
{
|
|
char *r = i < -1 ? p0 - 2 : i < 0 ? p0 - 1 : 1 < i ? p0 + 2 : p0 + 1;
|
|
|
|
free (p0); // { dg-message "call to 'free'" }
|
|
return *r; // { dg-warning "pointer used after 'free'" }
|
|
}
|
|
|
|
int warn_cond_loop (char *p)
|
|
{
|
|
char *q = p;
|
|
|
|
/* -fno-tree-loop-distribute-patterns ensures this does not get converted
|
|
into rawmemchr (making q and p unrelated). */
|
|
while (*q)
|
|
++q;
|
|
|
|
free (p); // { dg-message "call to 'free'" }
|
|
return *q; // { dg-warning "pointer 'q' used after 'free'" }
|
|
}
|