On 8/27/19 3:09 AM, Christophe Lyon wrote:
On Fri, 23 Aug 2019 at 04:14, Jeff Law <l...@redhat.com> wrote:

On 8/12/19 4:09 PM, Martin Sebor wrote:


gcc-83431.diff

PR tree-optimization/83431 - -Wformat-truncation may incorrectly report 
truncation

gcc/ChangeLog:

       PR c++/83431
       * gimple-ssa-sprintf.c (pass_data_sprintf_length): Remove object.
       (sprintf_dom_walker): Remove class.
       (get_int_range): Make argument const.
       (directive::fmtfunc, directive::set_precision): Same.
       (format_none): Same.
       (build_intmax_type_nodes): Same.
       (adjust_range_for_overflow): Same.
       (format_floating): Same.
       (format_character): Same.
       (format_string): Same.
       (format_plain): Same.
       (get_int_range): Cast away constness.
       (format_integer): Same.
       (get_string_length): Call get_range_strlen_dynamic.  Handle
       null lendata.maxbound.
       (should_warn_p): Adjust argument scope qualifier.
       (maybe_warn): Same.
       (format_directive): Same.
       (parse_directive): Same.
       (is_call_safe): Same.
       (try_substitute_return_value): Same.
       (sprintf_dom_walker::handle_printf_call): Rename...
       (handle_printf_call): ...to this.  Initialize target to host charmap
       here instead of in pass_sprintf_length::execute.
       (struct call_info): Make global.
       (sprintf_dom_walker::compute_format_length): Make global.
       (sprintf_dom_walker::handle_gimple_call): Same.
       * passes.def (pass_sprintf_length): Replace with pass_strlen.
       * print-rtl.c (print_pattern): Reduce the number of spaces to
       avoid -Wformat-truncation.
       * tree-pass.h (make_pass_warn_printf): New function.
       * tree-ssa-strlen.c (strlen_optimize): New variable.
       (get_string_length): Add comments.
       (get_range_strlen_dynamic): New function.
       (check_and_optimize_call): New function.
       (handle_integral_assign): New function.
       (strlen_check_and_optimize_stmt): Factor code out into
       strlen_check_and_optimize_call and handle_integral_assign.
       (strlen_dom_walker::evrp): New member.
       (strlen_dom_walker::before_dom_children): Use evrp member.
       (strlen_dom_walker::after_dom_children): Use evrp member.
       (printf_strlen_execute): New function.
       (pass_strlen::gate): Update to handle printf calls.
       (dump_strlen_info): New function.
       (pass_data_warn_printf): New variable.
       (pass_warn_printf): New class.
       * tree-ssa-strlen.h (get_range_strlen_dynamic): Declare.
       (handle_printf_call): Same.

gcc/testsuite/ChangeLog:

       PR c++/83431
       * gcc.dg/strlenopt-63.c: New test.
       * gcc.dg/pr79538.c: Adjust text of expected warning.
       * gcc.dg/pr81292-1.c: Adjust pass name.
       * gcc.dg/pr81292-2.c: Same.
       * gcc.dg/pr81703.c: Same.
       * gcc.dg/strcmpopt_2.c: Same.
       * gcc.dg/strcmpopt_3.c: Same.
       * gcc.dg/strcmpopt_4.c: Same.
       * gcc.dg/strlenopt-1.c: Same.
       * gcc.dg/strlenopt-10.c: Same.
       * gcc.dg/strlenopt-11.c: Same.
       * gcc.dg/strlenopt-13.c: Same.
       * gcc.dg/strlenopt-14g.c: Same.
       * gcc.dg/strlenopt-14gf.c: Same.
       * gcc.dg/strlenopt-15.c: Same.
       * gcc.dg/strlenopt-16g.c: Same.
       * gcc.dg/strlenopt-17g.c: Same.
       * gcc.dg/strlenopt-18g.c: Same.
       * gcc.dg/strlenopt-19.c: Same.
       * gcc.dg/strlenopt-1f.c: Same.
       * gcc.dg/strlenopt-2.c: Same.
       * gcc.dg/strlenopt-20.c: Same.
       * gcc.dg/strlenopt-21.c: Same.
       * gcc.dg/strlenopt-22.c: Same.
       * gcc.dg/strlenopt-22g.c: Same.
       * gcc.dg/strlenopt-24.c: Same.
       * gcc.dg/strlenopt-25.c: Same.
       * gcc.dg/strlenopt-26.c: Same.
       * gcc.dg/strlenopt-27.c: Same.
       * gcc.dg/strlenopt-28.c: Same.
       * gcc.dg/strlenopt-29.c: Same.
       * gcc.dg/strlenopt-2f.c: Same.
       * gcc.dg/strlenopt-3.c: Same.
       * gcc.dg/strlenopt-30.c: Same.
       * gcc.dg/strlenopt-31g.c: Same.
       * gcc.dg/strlenopt-32.c: Same.
       * gcc.dg/strlenopt-33.c: Same.
       * gcc.dg/strlenopt-33g.c: Same.
       * gcc.dg/strlenopt-34.c: Same.
       * gcc.dg/strlenopt-35.c: Same.
       * gcc.dg/strlenopt-4.c: Same.
       * gcc.dg/strlenopt-48.c: Same.
       * gcc.dg/strlenopt-49.c: Same.
       * gcc.dg/strlenopt-4g.c: Same.
       * gcc.dg/strlenopt-4gf.c: Same.
       * gcc.dg/strlenopt-5.c: Same.
       * gcc.dg/strlenopt-50.c: Same.
       * gcc.dg/strlenopt-51.c: Same.
       * gcc.dg/strlenopt-52.c: Same.
       * gcc.dg/strlenopt-53.c: Same.
       * gcc.dg/strlenopt-54.c: Same.
       * gcc.dg/strlenopt-55.c: Same.
       * gcc.dg/strlenopt-56.c: Same.
       * gcc.dg/strlenopt-6.c: Same.
       * gcc.dg/strlenopt-61.c: Same.
       * gcc.dg/strlenopt-7.c: Same.
       * gcc.dg/strlenopt-8.c: Same.
       * gcc.dg/strlenopt-9.c: Same.
       * gcc.dg/strlenopt.h (snprintf, snprintf): Declare.
       * gcc.dg/tree-ssa/builtin-snprintf-6.c: New test.
       * gcc.dg/tree-ssa/builtin-snprintf-7.c: New test.
       * gcc.dg/tree-ssa/builtin-snprintf-8.c: New test.
       * gcc.dg/tree-ssa/builtin-snprintf-9.c: New test.
       * gcc.dg/tree-ssa/builtin-sprintf-warn-21.c: New test.
       * gcc.dg/tree-ssa/dump-4.c: New test.
       * gcc.dg/tree-ssa/pr83501.c: Adjust pass name.


OK for the trunk.  Sorry this took so long.


Hi!

It seems this patch is causing bootstrap failure on arm (and
apparently on i686 according to gcc-testresults).
I've noticed:
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:1743:24:
error: ‘(c)=c ## ’ directive output between 9 and 9 bytes may
cause result to exceed ‘INT_MAX’ [-Werror=format-overflow=]
00:27:03  1743 |       sprintf (buf, "%s(c)=c ## %s", macro, suffix);
00:27:03       |                        ^~~~~~~~~
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:1738:24:
error: ‘(c)=c’ directive output between 5 and 5 bytes may cause
result to exceed ‘INT_MAX’ [-Werror=format-overflow=]
00:27:03  1738 |       sprintf (buf, "%s(c)=c", macro);
00:27:03       |                        ^~~~~
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c/gimple-parser.c:
In function ‘void c_parser_parse_gimple_body(c_parser*, char*,
c_declspec_il, profile_count)’:
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c/gimple-parser.c:212:1:
note: parameter passing for argument of type ‘profile_count’
changed in GCC 9.1
00:27:03   212 | c_parser_parse_gimple_body (c_parser *cparser, char
*gimple_pass,
00:27:03       | ^~~~~~~~~~~~~~~~~~~~~~~~~~
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:
In function ‘void builtin_define_type_minmax(const char*, const
char*, tree)’:
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:1823:21:
error: ‘%s’ directive output between 0 and 131 bytes may cause
result to exceed ‘INT_MAX’ [-Werror=format-overflow=]
00:27:03  1823 |   sprintf (buf, "%s=%s%s", max_macro, value, suffix);
00:27:03       |                     ^~                ~~~~~
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:1838:21:
error: ‘=(-’ directive output between 3 and 3 bytes may cause
result to exceed ‘INT_MAX’ [-Werror=format-overflow=]
00:27:03  1838 |    sprintf (buf, "%s=(-%s - 1)", min_macro, max_macro);
00:27:03       |                     ^~~
00:27:03 
/home/tcwg-buildslave/workspace/tcwg_gnu_0/abe/snapshots/gcc.git~master/gcc/c-family/c-cppbuiltin.c:1832:21:
error: ‘=0’ directive output between 2 and 2 bytes may cause
result to exceed ‘INT_MAX’ [-Werror=format-overflow=]
00:27:03  1832 |    sprintf (buf, "%s=0%s", min_macro, suffix);
00:27:03       |                     ^~

On arm still, I've noticed failures to build glibc-2.29:
res_query.c: In function '__res_context_querydomain':
res_query.c:591:18: error: '%s' directive writing up to 2147483646
bytes into a region of size 1025 [-Werror=format-overflow=]
   591 |   sprintf(nbuf, "%s.%s", name, domain);
       |                  ^~
res_query.c:591:3: note: 'sprintf' output between 2 and 4294967293
bytes into a destination of size 1025
   591 |   sprintf(nbuf, "%s.%s", name, domain);
       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Can you have a look?

I can reproduce the ILP32 warnings.  I suspect those in the ARM
Glibc build are caused by the same issue as in the i386 build.
On an LP64 host with an ILP32 target the range of lengths of
an unknown string is computed as [0, PTRDIFF_MAX - 2] when on
LP64 it's [0, SIZE_MAX].  The caller expects only the latter
to mean an unknown string with any length.

Martin

Reply via email to