diff options
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r-- | gcc/gimple-fold.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 42673b5..07341eb 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1275,11 +1275,13 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len) Set *FLEXP to true if the range of the string lengths has been obtained from the upper bound of an array at the end of a struct. Such an array may hold a string that's longer than its upper bound - due to it being used as a poor-man's flexible array member. */ + due to it being used as a poor-man's flexible array member. + ELTSIZE is 1 for normal single byte character strings, and 2 or + 4 for wide characer strings. ELTSIZE is by default 1. */ static bool get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, - int fuzzy, bool *flexp) + int fuzzy, bool *flexp, unsigned eltsize = 1) { tree var, val = NULL_TREE; gimple *def_stmt; @@ -1300,8 +1302,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, tree aop0 = TREE_OPERAND (op, 0); if (TREE_CODE (aop0) == INDIRECT_REF && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME) - return get_range_strlen (TREE_OPERAND (aop0, 0), - length, visited, type, fuzzy, flexp); + return get_range_strlen (TREE_OPERAND (aop0, 0), length, + visited, type, fuzzy, flexp, eltsize); } else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF && fuzzy) { @@ -1329,13 +1331,13 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, return false; } else - val = c_strlen (arg, 1); + val = c_strlen (arg, 1, eltsize); if (!val && fuzzy) { if (TREE_CODE (arg) == ADDR_EXPR) return get_range_strlen (TREE_OPERAND (arg, 0), length, - visited, type, fuzzy, flexp); + visited, type, fuzzy, flexp, eltsize); if (TREE_CODE (arg) == ARRAY_REF) { @@ -1477,7 +1479,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, || gimple_assign_unary_nop_p (def_stmt)) { tree rhs = gimple_assign_rhs1 (def_stmt); - return get_range_strlen (rhs, length, visited, type, fuzzy, flexp); + return get_range_strlen (rhs, length, visited, type, fuzzy, flexp, + eltsize); } else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR) { @@ -1486,7 +1489,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, for (unsigned int i = 0; i < 2; i++) if (!get_range_strlen (ops[i], length, visited, type, fuzzy, - flexp)) + flexp, eltsize)) { if (fuzzy == 2) *maxlen = build_all_ones_cst (size_type_node); @@ -1513,7 +1516,8 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, if (arg == gimple_phi_result (def_stmt)) continue; - if (!get_range_strlen (arg, length, visited, type, fuzzy, flexp)) + if (!get_range_strlen (arg, length, visited, type, fuzzy, flexp, + eltsize)) { if (fuzzy == 2) *maxlen = build_all_ones_cst (size_type_node); @@ -1545,10 +1549,13 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, and false if PHIs and COND_EXPRs are to be handled optimistically, if we can determine string length minimum and maximum; it will use the minimum from the ones where it can be determined. - STRICT false should be only used for warning code. */ + STRICT false should be only used for warning code. + + ELTSIZE is 1 for normal single byte character strings, and 2 or + 4 for wide characer strings. ELTSIZE is by default 1. */ bool -get_range_strlen (tree arg, tree minmaxlen[2], bool strict) +get_range_strlen (tree arg, tree minmaxlen[2], unsigned eltsize, bool strict) { bitmap visited = NULL; @@ -1557,7 +1564,7 @@ get_range_strlen (tree arg, tree minmaxlen[2], bool strict) bool flexarray = false; if (!get_range_strlen (arg, minmaxlen, &visited, 1, strict ? 1 : 2, - &flexarray)) + &flexarray, eltsize)) { minmaxlen[0] = NULL_TREE; minmaxlen[1] = NULL_TREE; @@ -3500,7 +3507,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) wide_int maxlen; tree lenrange[2]; - if (!get_range_strlen (gimple_call_arg (stmt, 0), lenrange, true) + if (!get_range_strlen (gimple_call_arg (stmt, 0), lenrange, 1, true) && lenrange[0] && TREE_CODE (lenrange[0]) == INTEGER_CST && lenrange[1] && TREE_CODE (lenrange[1]) == INTEGER_CST) { |