So this is the infrastructure changes necessary to enable Martin's patch to detect strings without NUL termination passed to the sprintf routines. There's three tightly related changes.
First in get_range_strlen, we verify that c_strlen found an unterminated string before setting *nonstr. Second, also in get_range_strlen, in the event we encounter an unterminated string, we still want to bubble up the min/max lengths. The sprintf code will check those against the directive's specified length. If the length specified by the sprintf directive ensures we won't walk off the end of the string, then the warning is suppressed. Bubbling those lengths up caused heartburn for the strlen folding bits which blindly looked at the returned min/max without first verifying that the string was properly terminated. So the 3rd hunk disables strlen folding when get_range_strlen indicates the string was not properly terminated. Bootstrapped and regression tested both in isolation and with Martin's patch to warn for unterminated strings used in sprintf calls. Installing on the trunk. I'll be installing Martin's patch momentarily as well. Jeff
commit 89d3e5cf174b6555ba76eb4bef49555fe00fc5b6 Author: Jeff Law <l...@torsion.usersys.redhat.com> Date: Wed Oct 3 12:02:12 2018 -0400 * gimple-fold.c (get_range_strlen): Only set *nonstr when an unterminated string is discovered. Bubble up range even for unterminated strings. (gimple_fold_builtin_strlen): Do not fold if get_range_strlen indicates the string was not terminated via NONSTR. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6acb077b357..aa10aa07269 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,12 @@ -2018-10-3 Aldy Hernandez <al...@redhat.com> +2018-10-02 Jeff Law <l...@redhat.com> + + * gimple-fold.c (get_range_strlen): Only set *nonstr when + an unterminated string is discovered. Bubble up range + even for unterminated strings. + (gimple_fold_builtin_strlen): Do not fold if get_range_strlen + indicates the string was not terminated via NONSTR. + +2018-10-03 Aldy Hernandez <al...@redhat.com> * tree-vrp.c (extract_range_from_unary_expr): Special case all pointer conversions. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fa1fc60876c..fe6bc08bdd9 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1344,8 +1344,13 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, /* If we potentially had a non-terminated string, then bubble that information up to the caller. */ - if (!val) - *nonstr = data.decl; + if (!val && data.decl) + { + *nonstr = data.decl; + *minlen = data.len; + *maxlen = data.len; + return type == 0 ? false : true; + } } if (!val && fuzzy) @@ -3596,6 +3601,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi) tree nonstr; tree lenrange[2]; if (!get_range_strlen (arg, lenrange, 1, true, &nonstr) + && !nonstr && lenrange[0] && TREE_CODE (lenrange[0]) == INTEGER_CST && lenrange[1] && TREE_CODE (lenrange[1]) == INTEGER_CST) {