aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2018-07-11 15:30:51 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2018-07-11 15:30:51 +0000
commit288aaa5f852b6f93078e15b7ac17af3b4930decd (patch)
tree774a14ad8d1ed095e9895cd329d92655d84195e0 /gcc/gimple.c
parentdff2abcbee65dbb4b7ca3ade0f7622ffdc0af391 (diff)
downloadgcc-288aaa5f852b6f93078e15b7ac17af3b4930decd.zip
gcc-288aaa5f852b6f93078e15b7ac17af3b4930decd.tar.gz
gcc-288aaa5f852b6f93078e15b7ac17af3b4930decd.tar.bz2
vr-values.c (gimple_stmt_nonzero_p): Abstract common code to...
* vr-values.c (gimple_stmt_nonzero_p): Abstract common code to... * gimple.c (gimple_call_nonnull_result_p): ...here... (gimple_call_nonnull_arg): ...and here. * gimple.h (gimple_call_nonnull_result_p): New. (gimple_call_nonnull_arg): New. From-SVN: r262557
Diffstat (limited to 'gcc/gimple.c')
-rw-r--r--gcc/gimple.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/gcc/gimple.c b/gcc/gimple.c
index afdf583..8d56a96 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1548,6 +1548,57 @@ gimple_call_return_flags (const gcall *stmt)
}
+/* Return true if call STMT is known to return a non-zero result. */
+
+bool
+gimple_call_nonnull_result_p (gcall *call)
+{
+ tree fndecl = gimple_call_fndecl (call);
+ if (!fndecl)
+ return false;
+ if (flag_delete_null_pointer_checks && !flag_check_new
+ && DECL_IS_OPERATOR_NEW (fndecl)
+ && !TREE_NOTHROW (fndecl))
+ return true;
+
+ /* References are always non-NULL. */
+ if (flag_delete_null_pointer_checks
+ && TREE_CODE (TREE_TYPE (fndecl)) == REFERENCE_TYPE)
+ return true;
+
+ if (flag_delete_null_pointer_checks
+ && lookup_attribute ("returns_nonnull",
+ TYPE_ATTRIBUTES (gimple_call_fntype (call))))
+ return true;
+ return gimple_alloca_call_p (call);
+}
+
+
+/* If CALL returns a non-null result in an argument, return that arg. */
+
+tree
+gimple_call_nonnull_arg (gcall *call)
+{
+ tree fndecl = gimple_call_fndecl (call);
+ if (!fndecl)
+ return NULL_TREE;
+
+ unsigned rf = gimple_call_return_flags (call);
+ if (rf & ERF_RETURNS_ARG)
+ {
+ unsigned argnum = rf & ERF_RETURN_ARG_MASK;
+ if (argnum < gimple_call_num_args (call))
+ {
+ tree arg = gimple_call_arg (call, argnum);
+ if (SSA_VAR_P (arg)
+ && infer_nonnull_range_by_attribute (call, arg))
+ return arg;
+ }
+ }
+ return NULL_TREE;
+}
+
+
/* Return true if GS is a copy assignment. */
bool