aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple.cc')
-rw-r--r--gcc/gimple.cc45
1 files changed, 24 insertions, 21 deletions
diff --git a/gcc/gimple.cc b/gcc/gimple.cc
index 9acfa38..41908d4 100644
--- a/gcc/gimple.cc
+++ b/gcc/gimple.cc
@@ -2916,15 +2916,7 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl)
return true;
tree arg = gimple_call_arg (stmt, i);
tree type = TREE_VALUE (targs);
- if (!useless_type_conversion_p (type, TREE_TYPE (arg))
- /* char/short integral arguments are promoted to int
- by several frontends if targetm.calls.promote_prototypes
- is true. Allow such promotion too. */
- && !(INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
- && targetm.calls.promote_prototypes (TREE_TYPE (fndecl))
- && useless_type_conversion_p (integer_type_node,
- TREE_TYPE (arg))))
+ if (!useless_type_conversion_p (type, TREE_TYPE (arg)))
return false;
targs = TREE_CHAIN (targs);
}
@@ -3162,16 +3154,20 @@ infer_nonnull_range_by_dereference (gimple *stmt, tree op)
}
/* Return true if OP can be inferred to be a non-NULL after STMT
- executes by using attributes. If OP2 is non-NULL and nonnull_if_nonzero
- is the only attribute implying OP being non-NULL and the corresponding
- argument isn't non-zero INTEGER_CST, set *OP2 to the corresponding
- argument and return true (in that case returning true doesn't mean
- OP can be unconditionally inferred to be non-NULL, but conditionally). */
+ executes by using attributes. If OP2 and OP3 are non-NULL and
+ nonnull_if_nonzero is the only attribute implying OP being non-NULL
+ and the corresponding argument(s) aren't non-zero INTEGER_CST, set *OP2
+ and *OP3 to the corresponding arguments and return true (in that case
+ returning true doesn't mean OP can be unconditionally inferred to be
+ non-NULL, but conditionally). */
bool
-infer_nonnull_range_by_attribute (gimple *stmt, tree op, tree *op2)
+infer_nonnull_range_by_attribute (gimple *stmt, tree op, tree *op2, tree *op3)
{
if (op2)
- *op2 = NULL_TREE;
+ {
+ *op2 = NULL_TREE;
+ *op3 = NULL_TREE;
+ }
/* We can only assume that a pointer dereference will yield
non-NULL if -fdelete-null-pointer-checks is enabled. */
@@ -3228,26 +3224,33 @@ infer_nonnull_range_by_attribute (gimple *stmt, tree op, tree *op2)
unsigned int idx = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
unsigned int idx2
= TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
+ unsigned int idx3 = idx2;
+ if (tree chain2 = TREE_CHAIN (TREE_CHAIN (args)))
+ idx3 = TREE_INT_CST_LOW (TREE_VALUE (chain2)) - 1;
if (idx < gimple_call_num_args (stmt)
&& idx2 < gimple_call_num_args (stmt)
+ && idx3 < gimple_call_num_args (stmt)
&& operand_equal_p (op, gimple_call_arg (stmt, idx), 0))
{
tree arg2 = gimple_call_arg (stmt, idx2);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
+ tree arg3 = gimple_call_arg (stmt, idx3);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))
+ || !INTEGRAL_TYPE_P (TREE_TYPE (arg3)))
return false;
- if (integer_nonzerop (arg2))
+ if (integer_nonzerop (arg2) && integer_nonzerop (arg3))
return true;
- if (integer_zerop (arg2))
+ if (integer_zerop (arg2) || integer_zerop (arg3))
return false;
if (op2)
{
/* This case is meant for ubsan instrumentation.
- The caller can check at runtime if *OP2 is
+ The caller can check at runtime if *OP2 and *OP3 are
non-zero and OP is null. */
*op2 = arg2;
+ *op3 = arg3;
return true;
}
- return tree_expr_nonzero_p (arg2);
+ return tree_expr_nonzero_p (arg2) && tree_expr_nonzero_p (arg3);
}
}
}