arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
}
else if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
- && callfn && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callfn)))
- arg1 = 0;
+ && callfn
+ && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callfn)))
+ arg1 = 0;
/* Non-const arguments are OK here, let the caller handle constness. */
- if (arg1 < 0 || arg1 >= (int) gimple_call_num_args (call)
- || arg2 >= (int) gimple_call_num_args (call))
+ if (arg1 < 0
+ || (unsigned) arg1 >= gimple_call_num_args (call)
+ || (arg2 >= 0 && (unsigned) arg2 >= gimple_call_num_args (call)))
return size_unknown (object_size_type);
+ tree targ1 = gimple_call_arg (call, arg1);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (targ1))
+ || TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (sizetype))
+ return size_unknown (object_size_type);
+ targ1 = fold_convert (sizetype, targ1);
tree bytes = NULL_TREE;
if (arg2 >= 0)
- bytes = size_binop (MULT_EXPR,
- fold_convert (sizetype, gimple_call_arg (call, arg1)),
- fold_convert (sizetype, gimple_call_arg (call, arg2)));
- else if (arg1 >= 0)
- bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
+ {
+ tree targ2 = gimple_call_arg (call, arg2);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (targ2))
+ || TYPE_PRECISION (TREE_TYPE (targ2)) > TYPE_PRECISION (sizetype))
+ return size_unknown (object_size_type);
+ targ2 = fold_convert (sizetype, targ2);
+ bytes = size_binop (MULT_EXPR, targ1, targ2);
+ }
+ else
+ bytes = targ1;
return bytes ? bytes : size_unknown (object_size_type);
}