diff options
-rw-r--r-- | gcc/gimple-ssa-warn-access.cc | 28 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/Wuse-after-free-6.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wuse-after-free-2.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c | 41 |
4 files changed, 60 insertions, 19 deletions
diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index fbb9b10..88d4469 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -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); diff --git a/gcc/testsuite/c-c++-common/Wuse-after-free-6.c b/gcc/testsuite/c-c++-common/Wuse-after-free-6.c index 581b1a0..0c17a25 100644 --- a/gcc/testsuite/c-c++-common/Wuse-after-free-6.c +++ b/gcc/testsuite/c-c++-common/Wuse-after-free-6.c @@ -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; } diff --git a/gcc/testsuite/gcc.dg/Wuse-after-free-2.c b/gcc/testsuite/gcc.dg/Wuse-after-free-2.c index ebc0516..ac174fd 100644 --- a/gcc/testsuite/gcc.dg/Wuse-after-free-2.c +++ b/gcc/testsuite/gcc.dg/Wuse-after-free-2.c @@ -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) diff --git a/gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c b/gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c new file mode 100644 index 0000000..ece066d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c @@ -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; +} |