aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-uninit.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-07-27 16:02:54 -0600
committerMartin Sebor <msebor@redhat.com>2021-07-27 16:02:54 -0600
commit6aacd901b800ee8a2a03123669b299a08aad0504 (patch)
tree92b704e894cabafe841d622922d28b8ad2dfa540 /gcc/tree-ssa-uninit.c
parent9360d6cd1706882dfffd3c7a08b5956c37207a11 (diff)
downloadgcc-6aacd901b800ee8a2a03123669b299a08aad0504.zip
gcc-6aacd901b800ee8a2a03123669b299a08aad0504.tar.gz
gcc-6aacd901b800ee8a2a03123669b299a08aad0504.tar.bz2
Let -Wuninitialized assume built-ins don't change const arguments [PR101584].
PR tree-optimization/101584 - missing -Wuninitialized with an allocated object after a built-in call gcc/ChangeLog: PR tree-optimization/101584 * tree-ssa-uninit.c (builtin_call_nomodifying_p): New function. (check_defs): Call it. gcc/testsuite/ChangeLog: PR tree-optimization/101584 * gcc.dg/uninit-38.c: Remove assertions. * gcc.dg/uninit-41.c: New test.
Diffstat (limited to 'gcc/tree-ssa-uninit.c')
-rw-r--r--gcc/tree-ssa-uninit.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 718b326..ab64a68 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -219,6 +219,70 @@ struct check_defs_data
bool found_may_defs;
};
+/* Return true if STMT is a call to built-in function all of whose
+ by-reference arguments are const-qualified (i.e., the function can
+ be assumed not to modify them). */
+
+static bool
+builtin_call_nomodifying_p (gimple *stmt)
+{
+ if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+ return false;
+
+ tree fndecl = gimple_call_fndecl (stmt);
+ if (!fndecl)
+ return false;
+
+ tree fntype = TREE_TYPE (fndecl);
+ if (!fntype)
+ return false;
+
+ /* Check the called function's signature for non-constc pointers.
+ If one is found, return false. */
+ unsigned argno = 0;
+ tree argtype;
+ function_args_iterator it;
+ FOREACH_FUNCTION_ARGS (fntype, argtype, it)
+ {
+ if (VOID_TYPE_P (argtype))
+ return true;
+
+ ++argno;
+
+ if (!POINTER_TYPE_P (argtype))
+ continue;
+
+ if (TYPE_READONLY (TREE_TYPE (argtype)))
+ continue;
+
+ return false;
+ }
+
+ /* If the number of actual arguments to the call is less than or
+ equal to the number of parameters, return false. */
+ unsigned nargs = gimple_call_num_args (stmt);
+ if (nargs <= argno)
+ return false;
+
+ /* Check arguments passed through the ellipsis in calls to variadic
+ functions for pointers. If one is found that's a non-constant
+ pointer, return false. */
+ for (; argno < nargs; ++argno)
+ {
+ tree arg = gimple_call_arg (stmt, argno);
+ argtype = TREE_TYPE (arg);
+ if (!POINTER_TYPE_P (argtype))
+ continue;
+
+ if (TYPE_READONLY (TREE_TYPE (argtype)))
+ continue;
+
+ return false;
+ }
+
+ return true;
+}
+
/* Callback for walk_aliased_vdefs. */
static bool
@@ -261,6 +325,9 @@ check_defs (ao_ref *ref, tree vdef, void *data_)
return false;
}
+ if (builtin_call_nomodifying_p (def_stmt))
+ return false;
+
/* Found a may-def on this path. */
data->found_may_defs = true;
return true;