aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/gimple-ssa-warn-access.cc28
-rw-r--r--gcc/testsuite/c-c++-common/Wuse-after-free-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wuse-after-free-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wuse-after-free-pr109123.c41
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(&regions->xy, lx);
+ return 0;
+}