[Bug c/106039] New: Inconsistent error reporting for printf() when format string is a macro

jonathan.leffler at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Jun 21 00:44:45 GMT 2022


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

            Bug ID: 106039
           Summary: Inconsistent error reporting for printf() when format
                    string is a macro
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jonathan.leffler at gmail dot com
  Target Milestone: ---

Created attachment 53176
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53176&action=edit
Preprocessed output

The problem is inconsistent error (warning) reporting from GCC
(home-built versions 8.2.0, 9.3.0, 10.3.0, 11.2.0, 12.1.0 tested on RHEL
7.4) with respect to the location of the problem.  (The test case is
reduced from 5600 lines and 43 headers to 26 lines with two headers.
The code is thoroughly anonymized.)

There is no doubt that the errors reported are correct on a 64-bit
system; the problem is in the way that the location of the error is
reported.

The errors reported by GCC 12.1.0 (errors because of -Werror) are shown
below.  Other versions produce essentially the same output, though the
error formatting in 8.2.0 is somewhat different.  The first error
correctly lists the line causing the problem (line 18) as expected and
desired.  The other errors do not list the line causing the problem
properly.

The problem is surprisingly sensitive to the format string defined by
the macro and the arguments provided to the printf() call.  Some of the
variations which 'fix' the error reporting are mentioned in the comments
in the source.  Reordering the printf() statements doesn't alter which
printf() statements have the inconsistent error reporting.

If the format string is placed directly in the printf() statement, the
line is reported correctly.  Neither the optimization level (-O) nor the
debugging options (-g) seem to alter the behaviour.  Using -Wall enables
the relevant option; using -Werror ensures that rerunning 'make'
attempts to rebuild the object file.  The standard specified does not
seem to alter the behaviour (in either -std=cXX or -std=gnuXX formats).

Adding the -save-temps option to the compilation command line (to
generate the .i file as requested in the 'Reporting Bugs' page)
completely alters the error messages generated, giving the correct line
numbers but odd-ball highlighting of what's wrong.

----

$ gcc -std=c99 -Werror -Wall -c gcc-bug.c
gcc-bug.c: In function ‘print_lock’:
gcc-bug.c:4:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 2 has type ‘long int’ [-Werror=format=]
    4 | #define PRT_BR_HDR    "%-16x\n"
      |                       ^~~~~~~~~
gcc-bug.c:18:12: note: in expansion of macro ‘PRT_BR_HDR’
   18 |     printf(PRT_BR_HDR, (intptr_t) val1);
      |            ^~~~~~~~~~
gcc-bug.c:4:28: note: format string is defined here
    4 | #define PRT_BR_HDR    "%-16x\n"
      |                        ~~~~^
      |                            |
      |                            unsigned int
      |                        %-16lx
gcc-bug.c:5:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 3 has type ‘long int’ [-Werror=format=]
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:5:23: note: in definition of macro ‘PRT_BR_LN1’
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:5:34: note: format string is defined here
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                              ~~~~^
      |                                  |
      |                                  unsigned int
      |                              %-16lx
gcc-bug.c:5:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 4 has type ‘long int’ [-Werror=format=]
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:5:23: note: in definition of macro ‘PRT_BR_LN1’
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:5:40: note: format string is defined here
    5 | #define PRT_BR_LN1    "%-21s %-16x %-16x %-18s %-18s\n"
      |                                    ~~~~^
      |                                        |
      |                                        unsigned int
      |                                    %-16lx
gcc-bug.c:6:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 4 has type ‘long int’ [-Werror=format=]
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:6:23: note: in definition of macro ‘PRT_BR_LN2’
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:6:39: note: format string is defined here
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                                   ~~~~^
      |                                       |
      |                                       unsigned int
      |                                   %-16lx
gcc-bug.c:6:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 5 has type ‘long int’ [-Werror=format=]
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:6:23: note: in definition of macro ‘PRT_BR_LN2’
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:6:45: note: format string is defined here
    6 | #define PRT_BR_LN2    "%-12s %-8s %-16x %-16x %-18s %-18s\n"
      |                                         ~~~~^
      |                                             |
      |                                             unsigned int
      |                                         %-16lx
gcc-bug.c:7:23: error: format ‘%x’ expects argument of type ‘unsigned int’, but
argument 5 has type ‘long int’ [-Werror=format=]
    7 | #define PRT_BR_LN3    "%-12s %-8s %-16s %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:7:23: note: in definition of macro ‘PRT_BR_LN3’
    7 | #define PRT_BR_LN3    "%-12s %-8s %-16s %-16x %-18s %-18s\n"
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcc-bug.c:7:45: note: format string is defined here
    7 | #define PRT_BR_LN3    "%-12s %-8s %-16s %-16x %-18s %-18s\n"
      |                                         ~~~~^
      |                                             |
      |                                             unsigned int
      |                                         %-16lx
cc1: all warnings being treated as errors
$


More information about the Gcc-bugs mailing list