tree-optimization/109123 - run -Wuse-afer-free only early
The following switches the -Wuse-after-free diagnostics from emitted during the late access warning passes to the early access warning passes to make sure we run before passes performing code motion run which are the source of a lot of false positives on use-after-free not involving memory operations. The patch also fixes an issue in c-c++-common/Wuse-after-free-6.c and causes the name of the unused pointer to appear in the diagnostic for extra cases in gcc.dg/Wuse-after-free-2.c PR tree-optimization/109123 * gimple-ssa-warn-access.cc (pass_waccess::warn_invalid_pointer): Do not emit -Wuse-after-free late. (pass_waccess::check_call): Always check call pointer uses. * gcc.dg/Wuse-after-free-pr109123.c: New testcase. * gcc.dg/Wuse-after-free-2.c: Amend expected diagnostic with the name of the pointer. * c-c++-common/Wuse-after-free-6.c: Un-XFAIL case.
This commit is contained in:
parent
adb70c2d10
commit
0a07bfad12
4 changed files with 60 additions and 19 deletions
|
@ -3907,7 +3907,8 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt,
|
|||
|
||||
if (is_gimple_call (inval_stmt))
|
||||
{
|
||||
if ((equality && warn_use_after_free < 3)
|
||||
if (!m_early_checks_p
|
||||
|| (equality && warn_use_after_free < 3)
|
||||
|| (maybe && warn_use_after_free < 2)
|
||||
|| warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
|
||||
return;
|
||||
|
@ -4303,19 +4304,18 @@ pass_waccess::check_call (gcall *stmt)
|
|||
if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
|
||||
check_builtin (stmt);
|
||||
|
||||
if (!m_early_checks_p)
|
||||
if (tree callee = gimple_call_fndecl (stmt))
|
||||
{
|
||||
/* Check for uses of the pointer passed to either a standard
|
||||
or a user-defined deallocation function. */
|
||||
unsigned argno = fndecl_dealloc_argno (callee);
|
||||
if (argno < (unsigned) call_nargs (stmt))
|
||||
{
|
||||
tree arg = call_arg (stmt, argno);
|
||||
if (TREE_CODE (arg) == SSA_NAME)
|
||||
check_pointer_uses (stmt, arg);
|
||||
}
|
||||
}
|
||||
if (tree callee = gimple_call_fndecl (stmt))
|
||||
{
|
||||
/* Check for uses of the pointer passed to either a standard
|
||||
or a user-defined deallocation function. */
|
||||
unsigned argno = fndecl_dealloc_argno (callee);
|
||||
if (argno < (unsigned) call_nargs (stmt))
|
||||
{
|
||||
tree arg = call_arg (stmt, argno);
|
||||
if (TREE_CODE (arg) == SSA_NAME)
|
||||
check_pointer_uses (stmt, arg);
|
||||
}
|
||||
}
|
||||
|
||||
check_call_access (stmt);
|
||||
check_call_dangling (stmt);
|
||||
|
|
|
@ -53,7 +53,7 @@ void* warn_cond_return_after_free (void *p, int c)
|
|||
free (p);
|
||||
// PHI handling not fully implemented.
|
||||
if (c)
|
||||
return p; // { dg-warning "pointer 'p' may be used" "pr??????" { xfail *-*-* } }
|
||||
return p; // { dg-warning "pointer 'p' may be used" }
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ void warn_cond_2_cst (char *p, int i)
|
|||
char *r = i ? p + 1 : p + 2;
|
||||
|
||||
free (p); // { dg-message "call to 'free'" }
|
||||
sink (r); // { dg-warning "pointer used after 'free'" }
|
||||
sink (r); // { dg-warning "pointer 'r' used after 'free'" }
|
||||
}
|
||||
|
||||
void warn_cond_2_var (char *p, int i, int j)
|
||||
|
@ -84,7 +84,7 @@ 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'" }
|
||||
sink (r); // { dg-warning "pointer 'r' used after 'free'" }
|
||||
}
|
||||
|
||||
void warn_cond_3_var (char *p0, int i, int j)
|
||||
|
@ -92,7 +92,7 @@ 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'" }
|
||||
sink (r + 1); // { dg-warning "pointer 'r' used after 'free'" }
|
||||
}
|
||||
|
||||
int warn_cond_4 (char *p0, char *q0, int i)
|
||||
|
@ -100,7 +100,7 @@ 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'" }
|
||||
return *r; // { dg-warning "pointer 'r' used after 'free'" }
|
||||
}
|
||||
|
||||
int warn_cond_loop (char *p)
|
||||
|
|
41
gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c
Normal file
41
gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -Wall" } */
|
||||
|
||||
typedef long unsigned int size_t;
|
||||
extern void *realloc (void *__ptr, size_t __size)
|
||||
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__warn_unused_result__)) __attribute__ ((__alloc_size__ (2)));
|
||||
struct vector_objective;
|
||||
typedef struct vector_objective vector_objective;
|
||||
struct vector_objective { double *_begin; double *_end; double *_capacity; };
|
||||
static inline size_t vector_objective_size(const vector_objective * v) {
|
||||
return v->_end - v->_begin; /* { dg-bogus "used after" } */
|
||||
}
|
||||
static inline size_t vector_objective_capacity(const vector_objective * v) {
|
||||
return v->_capacity - v->_begin;
|
||||
}
|
||||
static inline void vector_objective_reserve(vector_objective * v, size_t n) {
|
||||
size_t old_capacity = vector_objective_capacity(v);
|
||||
size_t old_size = vector_objective_size(v);
|
||||
if (n > old_capacity) {
|
||||
v->_begin = realloc(v->_begin, sizeof(double) * n);
|
||||
v->_end = v->_begin + old_size;
|
||||
v->_capacity = v->_begin + n;
|
||||
}
|
||||
}
|
||||
static inline void vector_objective_push_back(vector_objective * v, double x) {
|
||||
if (v->_end == v->_capacity)
|
||||
vector_objective_reserve (v, (vector_objective_capacity (v) == 0) ? 8 : 2 * vector_objective_capacity (v));
|
||||
*(v->_end) = x;
|
||||
v->_end++;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
vector_objective xy;
|
||||
} eaf_polygon_t;
|
||||
|
||||
int
|
||||
rectangle_add(eaf_polygon_t * regions, double lx)
|
||||
{
|
||||
vector_objective_push_back(®ions->xy, lx);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue