diff options
author | Martin Sebor <msebor@redhat.com> | 2021-07-27 16:02:54 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-07-27 16:02:54 -0600 |
commit | 6aacd901b800ee8a2a03123669b299a08aad0504 (patch) | |
tree | 92b704e894cabafe841d622922d28b8ad2dfa540 /gcc/tree-ssa-uninit.c | |
parent | 9360d6cd1706882dfffd3c7a08b5956c37207a11 (diff) | |
download | gcc-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.c | 67 |
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; |