https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87059

--- Comment #8 from Aldy Hernandez <aldyh at redhat dot com> ---
On 08/23/2018 04:08 PM, msebor at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87059
> 
> --- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
> The MIN_EXPR code predates my change -- r255898 just moved indentation.  Based
> on past experience I would assume MIN_EXPR to need the same types.  The code 
> in
> expand_builtin_strncmp mixes ssizetype and sizetype:
> 
>      len1 = c_strlen (arg1, 1);   // returns ssizetype
>      len2 = c_strlen (arg2, 1);
> 
>      if (len1)
>        len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
>      if (len2)
>        len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
> 
>      len3 = fold_convert_loc (loc, sizetype, arg3);
>      ...
>      if (len != len3)
>        len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len, len3);
> 
> So the fix is presumably to change len3 to
> 
>      len3 = fold_convert_loc (loc, ssizetype, arg3);
> 
> Given the difference between sizetype and ssizetype is just one 's' it seems
> like an easy mistake to make.  If MIN_EXPR does, in fact, require arguments of
> the same type then adding an assertion to fold_binary_loc() to verify it would
> help expose these mistakes early.  I'm not sure what the right predicate is to
> use in the assertion.  Just compare TYPE_MAIN_VARIANT of the two argument 
> types
> for equality?
> 

Thanks.

Testing the following:

gcc/

        PR 87059/tree-optimization
        * builtins.c (expand_builtin_strncmp): Pass signed sizetype to
        fold_convert_loc.

diff --git a/gcc/builtins.c b/gcc/builtins.c
index b1a79f3f33f..7113d19aadf 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -4727,7 +4727,7 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED 
rtx target,
    if (len2)
      len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);

-  tree len3 = fold_convert_loc (loc, sizetype, arg3);
+  tree len3 = fold_convert_loc (loc, ssizetype, arg3);

    /* If we don't have a constant length for the first, use the length
       of the second, if we know it.  If neither string is constant length,

Reply via email to