Bug 95496 - [10/11/12/13 Regression] Bogus -Wformat-overflow= warnings with -fsanitize=undefined
Summary: [10/11/12/13 Regression] Bogus -Wformat-overflow= warnings with -fsanitize=un...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: sanitizer (show other bugs)
Version: 11.0
: P2 normal
Target Milestone: 10.5
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wformat-overflow
  Show dependency treegraph
 
Reported: 2020-06-03 11:28 UTC by H.J. Lu
Modified: 2022-06-28 10:40 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-06-03 00:00:00


Attachments
A testcase (67.44 KB, application/octet-stream)
2020-06-03 11:28 UTC, H.J. Lu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2020-06-03 11:28:12 UTC
Created attachment 48666 [details]
A testcase

GCC 10.1 gave

[hjl@gnu-cfl-2 tmp]$ gcc -Wall -S -O2 x.i -fsanitize=undefined
In function ‘pe_print_idata’,
    inlined from ‘_bfd_pe_print_private_bfd_data_common’ at peXXigen.c:2979:3:
peXXigen.c:1378:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1378:3: warning: null format string [-Wformat-overflow=]
In function ‘pe_print_edata’,
    inlined from ‘_bfd_pe_print_private_bfd_data_common’ at peXXigen.c:2980:3:
peXXigen.c:1713:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1719:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1716:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1719:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1719:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1737:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1744:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1740:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1744:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1744:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1747:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1750:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1750:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1755:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1760:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1760:3: warning: null format string [-Wformat-overflow=]
peXXigen.c:1760:3: warning: null format string [-Wformat-overflow=]
[hjl@gnu-cfl-2 tmp]$ 

GCC 9.3 is OK.
Comment 1 H.J. Lu 2020-06-03 12:39:25 UTC
It was caused by

commit 22fca489eaf98f2691772b51773a1e4eb7bb4ef2
Author: Martin Sebor <msebor@redhat.com>
Date:   Mon Aug 26 18:29:45 2019 +0000

    PR tree-optimization/83431 - -Wformat-truncation may incorrectly report trun
cation
    
    gcc/ChangeLog:
Comment 2 Martin Sebor 2020-06-03 15:52:42 UTC
The instrumentation added by the sanitizers is known to lead to introducing invalid code (typically by jump threading) that triggers spurious warnings.  The dump for the attached file shows a number of invalid calls to fprintf.  Some of those result in diagnostics (in fact, they all should).

The first one looks like this.  Note the tests for null and the subsequent uses of nulls in the fprintf calls:

  _707 = section_618->name;
  _708 = dcgettext ("bfd", "\nThe Export Tables (interpreted %s section contents)\n\n", 5);
  if (vfile_98(D) == 0B)
    goto <bb 222>; [0.00%]
  else
    goto <bb 224>; [100.00%]

  <bb 222> [count: 0]:
  __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data103);
  if (_708 == 0B)
    goto <bb 223>; [0.00%]
  else
    goto <bb 466>; [100.00%]

  <bb 223> [count: 0]:
  __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data104);
  fprintf (vfile_98(D), _708, _707);
  _709 = dcgettext ("bfd", "Export Flags \t\t\t%lx\n", 5);
  if (vfile_98(D) == 0B)
    goto <bb 225>; [0.00%]
  else
    goto <bb 226>; [100.00%]

  <bb 224> [local count: 7698574]:
  if (_708 == 0B)
    goto <bb 223>; [0.00%]
  else
    goto <bb 500>; [100.00%]

  <bb 225> [count: 0]:
  # _992 = PHI <_1012(466), _709(223)>
  __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data106);
  if (_992 == 0B)
    goto <bb 227>; [0.00%]
  else
    goto <bb 465>; [100.00%]

  <bb 226> [local count: 7698574]:
  # _2952 = PHI <_709(223), _1227(500)>
  if (_2952 == 0B)
    goto <bb 227>; [0.00%]
  else
    goto <bb 499>; [100.00%]

  <bb 227> [count: 0]:
  # _2558 = PHI <0B(225), 0B(226)>
  __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data107);
  fprintf (vfile_98(D), 0B, _637);   <<< null format: warning

The calls with the null format are first seen in the dom3 dump, just after thread3.  The instrumentation (and jump threading) and the warnings are inherently incompatible.  They need to cooperate to avoid the spurious warnings.  The sanitizers could mark up the code somehow to either keep jump threading from doing what it does or to let the warnings know the calls were synthesized.  Until something like this is implemented the guidance we have been giving to users is to expect false positives from the warnings when using sanitizers (or disable the warnings).

$ gcc -O2 -S -fsanitize=undefined -fdump-tree-strlen=/dev/stdout peXXigen.c | sed -n "/^_bfd_pe_print_private_bfd_data_commo/,/^}/p" | grep "fprintf (" | grep 0B
  fprintf (0B, "\nTime/Date\t\t%08lx", _26);
  fprintf (0B, "\nMajorLinkerVersion\t%d\n", _2667);
  fprintf (0B, "MinorLinkerVersion\t%d\n", _2958);
  fprintf (0B, "\nSectionAlignment\t%08x\n", _2856);
  fprintf (0B, "FileAlignment\t\t%08x\n", _2834);
  fprintf (0B, "MajorOSystemVersion\t%d\n", _2815);
  fprintf (0B, "MinorOSystemVersion\t%d\n", _2801);
  fprintf (0B, "MajorImageVersion\t%d\n", _2787);
  fprintf (0B, "MinorImageVersion\t%d\n", _2773);
  fprintf (0B, "MajorSubsystemVersion\t%d\n", _2766);
  fprintf (0B, "MinorSubsystemVersion\t%d\n", _2752);
  fprintf (0B, "Win32Version\t\t%08x\n", _2738);
  fprintf (0B, "SizeOfImage\t\t%08x\n", _2720);
  fprintf (0B, "SizeOfHeaders\t\t%08x\n", _2708);
  fprintf (0B, "CheckSum\t\t%08x\n", _2696);
  fprintf (0B, "\nDllCharacteristics\t%08x\n", _946);
  fprintf (0B, "\nLoaderFlags\t\t%08lx\n", _2618);
  fprintf (0B, "NumberOfRvaAndSizes\t%08lx\n", _2594);
  fprintf (0B, "Entry %1x ", j_2977);
  fprintf (0B, " %08lx ", _696);
  fprintf (vfile_98(D), 0B, _637);
  fprintf (vfile_98(D), 0B, _643);
  fprintf (vfile_98(D), 0B, _790, _780);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B, _676);
  fprintf (vfile_98(D), 0B, _682);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B);
  fprintf (0B, "   %x", em_data_1082);
  fprintf (0B, "Subsystem\t\t%08x", _2689);
  fprintf (0B, _1020);
  fprintf (0B, _721, _670);
  fprintf (0B, _708, _707);
  fprintf (0B, _851, _850, addr_852);
  fprintf (0B, "Subsystem\t\t%08x", _2689);
  fprintf (0B, "Magic\t\t\t%04x", _30);
  fprintf (0B, "Magic\t\t\t%04x", _30);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B);
  fprintf (vfile_98(D), 0B, _682);
  fprintf (vfile_98(D), 0B, _682);
  fprintf (vfile_98(D), 0B, _613, _606);
  fprintf (vfile_98(D), 0B, _2485, _2483);
  fprintf (vfile_98(D), 0B, _1136);
  fprintf (vfile_98(D), 0B, _232);
Comment 3 Martin Sebor 2020-06-03 16:37:34 UTC
See also pr87884.
Comment 4 Jakub Jelinek 2020-06-03 17:22:43 UTC
(In reply to Martin Sebor from comment #2)
> The instrumentation added by the sanitizers is known to lead to introducing
> invalid code (typically by jump threading) that triggers spurious warnings.

I don't think this is accurate description, the instrumentation doesn't lead to introduction of any invalid code, all it leads to is due to the instrumentation some code is less optimized.  It is the property of jump threading that it often can result in code that will actually never be executed (i.e. dead code), that can happen easily both with sanitization or if one adds whatever the sanitizer adds by hand.  And then the question is if the compiler is able to find out the code is dead and optimize it away before these warnings warn about it.
Comment 5 Richard Biener 2020-07-23 06:51:57 UTC
GCC 10.2 is released, adjusting target milestone.
Comment 6 Richard Biener 2021-04-08 12:02:23 UTC
GCC 10.3 is being released, retargeting bugs to GCC 10.4.
Comment 7 Jakub Jelinek 2022-06-28 10:40:56 UTC
GCC 10.4 is being released, retargeting bugs to GCC 10.5.