bool gimple_check_call_matching_types (gimple call_stmt, tree callee, bool args_count_match) { tree lhs; if ((DECL_RESULT (callee) && !DECL_BY_REFERENCE (DECL_RESULT (callee)) && (lhs = gimple_call_lhs (call_stmt)) != NULL_TREE && !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)), TREE_TYPE (lhs)) && !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs)) || !gimple_check_call_args (call_stmt, callee, args_count_match)) return false; return true; }
/* Build a constant tree with type TREE_TYPE and value according to LAT. Return the tree, or, if it is not possible to convert such value to TREE_TYPE, NULL. */ static tree build_const_val (struct ipcp_lattice *lat, tree tree_type) { tree val; gcc_assert (ipcp_lat_is_const (lat)); val = lat->constant; if (!useless_type_conversion_p (tree_type, TREE_TYPE (val))) { if (fold_convertible_p (tree_type, val)) return fold_build1 (NOP_EXPR, tree_type, val); else if (TYPE_SIZE (tree_type) == TYPE_SIZE (TREE_TYPE (val))) return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val); else return NULL; } return val; }
static bool gimple_check_call_args (gimple stmt, tree fndecl, bool args_count_match) { tree parms, p; unsigned int i, nargs; /* Calls to internal functions always match their signature. */ if (gimple_call_internal_p (stmt)) return true; nargs = gimple_call_num_args (stmt); /* Get argument types for verification. */ if (fndecl) parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); else parms = TYPE_ARG_TYPES (gimple_call_fntype (stmt)); /* Verify if the type of the argument matches that of the function declaration. If we cannot verify this or there is a mismatch, return false. */ if (fndecl && DECL_ARGUMENTS (fndecl)) { for (i = 0, p = DECL_ARGUMENTS (fndecl); i < nargs; i++, p = DECL_CHAIN (p)) { tree arg; /* We cannot distinguish a varargs function from the case of excess parameters, still deferring the inlining decision to the callee is possible. */ if (!p) break; arg = gimple_call_arg (stmt, i); if (p == error_mark_node || arg == error_mark_node || (!types_compatible_p (DECL_ARG_TYPE (p), TREE_TYPE (arg)) && !fold_convertible_p (DECL_ARG_TYPE (p), arg))) return false; } if (args_count_match && p) return false; } else if (parms) { for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p)) { tree arg; /* If this is a varargs function defer inlining decision to callee. */ if (!p) break; arg = gimple_call_arg (stmt, i); if (TREE_VALUE (p) == error_mark_node || arg == error_mark_node || TREE_CODE (TREE_VALUE (p)) == VOID_TYPE || (!types_compatible_p (TREE_VALUE (p), TREE_TYPE (arg)) && !fold_convertible_p (TREE_VALUE (p), arg))) return false; } } else { if (nargs != 0) return false; } return true; }