tree fold_const_call (built_in_function fn, tree type, tree arg0, tree arg1, tree arg2) { const char *p0, *p1; size_t s2; switch (fn) { case BUILT_IN_STRNCMP: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)) && host_size_t_cst_p (arg2, &s2)) return build_int_cst (type, strncmp (p0, p1, s2)); return NULL_TREE; case BUILT_IN_BCMP: case BUILT_IN_MEMCMP: if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)) && host_size_t_cst_p (arg2, &s2) && s2 <= strlen (p0) && s2 <= strlen (p1)) return build_cmp_result (type, memcmp (p0, p1, s2)); return NULL_TREE; default: return fold_const_call_1 (fn, type, arg0, arg1, arg2); } }
tree fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2) { const char *p0, *p1; char c; unsigned HOST_WIDE_INT s0, s1; size_t s2 = 0; switch (fn) { case CFN_BUILT_IN_STRNCMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1))) return build_int_cst (type, strncmp (p0, p1, s2)); return NULL_TREE; case CFN_BUILT_IN_STRNCASECMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); else if ((p0 = c_getstr (arg0)) && (p1 = c_getstr (arg1)) && strncmp (p0, p1, s2) == 0) return build_int_cst (type, 0); return NULL_TREE; case CFN_BUILT_IN_BCMP: case CFN_BUILT_IN_MEMCMP: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); if ((p0 = c_getstr (arg0, &s0)) && (p1 = c_getstr (arg1, &s1)) && s2 <= s0 && s2 <= s1) return build_cmp_result (type, memcmp (p0, p1, s2)); return NULL_TREE; case CFN_BUILT_IN_MEMCHR: if (!host_size_t_cst_p (arg2, &s2)) return NULL_TREE; if (s2 == 0 && !TREE_SIDE_EFFECTS (arg0) && !TREE_SIDE_EFFECTS (arg1)) return build_int_cst (type, 0); if ((p0 = c_getstr (arg0, &s0)) && s2 <= s0 && target_char_cst_p (arg1, &c)) { const char *r = (const char *) memchr (p0, c, s2); if (r == NULL) return build_int_cst (type, 0); return fold_convert (type, fold_build_pointer_plus_hwi (arg0, r - p0)); } return NULL_TREE; default: return fold_const_call_1 (fn, type, arg0, arg1, arg2); } }