On 12/04/2017 05:41 AM, Rainer Orth wrote:
Within test last week, 64-bit Solaris/SPARC bootstrap began to fail:

/vol/gcc/src/hg/trunk/local/gcc/dbxout.c: In function 'bool dbxout_block(tree, 
int, tree, int)':
/vol/gcc/src/hg/trunk/local/gcc/dbxout.c:3767:1: error: '%lu' directive writing 
between 1 and 20 bytes into a region of size 14 [-Werror=format-overflow=]
 dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 ^~~~~~~~~~~~
/vol/gcc/src/hg/trunk/local/gcc/dbxout.c:3767:1: note: directive argument in 
the range [0, 18446744073709551614]
In file included from ./tm.h:26,
                 from /vol/gcc/src/hg/trunk/local/gcc/target.h:52,
                 from /vol/gcc/src/hg/trunk/local/gcc/dbxout.c:72:
/vol/gcc/src/hg/trunk/local/gcc/config/sparc/sol2.h:353:11: note: 
'std::sprintf' output between 8 and 27 bytes into a destination of size 20
   sprintf ((LABEL), "*.L%s%lu", (PREFIX), (unsigned long)(NUM))
   ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/vol/gcc/src/hg/trunk/local/gcc/dbxout.c:3855:5: note: in expansion of macro 
'ASM_GENERATE_INTERNAL_LABEL'
     ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", parent_blocknum);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~

The line numbers are extremely confusing, to say the least, though: the
one in the error and the first note refer to the begin of the function
definition and only the third note refers to the line of the actual
error.

I agree it looks confusing.  It's the result of the interaction
between macro tracking and inlining.

I think it's a general problem that affects many (though not all)
warnings emitted out of the middle-end.  For instance, the example
below results in similar output.  The output changes depending on
whether or not _FORTIFY_SOURCE is defined.

#include <string.h>

#define FOO(d, s) strcpy (d, s)

void foo (char *d, const char *s) { FOO (d, s); }

void sink (char*);

void bar (void)
{
  char a[3];

  foo (a, "1234567");   // bug here

  sink (a);
}

Without _FORTIFY_SOURCE:

d.c: In function ‘void bar()’:
d.c:3:26: warning: ‘void* __builtin_memcpy(void*, const void*, long unsigned int)’ writing 8 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=]
 #define FOO(d, s) strcpy (d, s)
                   ~~~~~~~^~~~~~
d.c:5:37: note: in expansion of macro ‘FOO’
 void foo (char *d, const char *s) { FOO (d, s); }
                                     ^~~

If bar() were a bigger function with multiple calls to foo() it
could be tricky to tell which of them caused the warning.

With _FORTIFY_SOURCE:

In file included from /usr/include/string.h:635,
                 from d.c:1:
In function ‘char* strcpy(char*, const char*)’,
    inlined from ‘void bar()’ at d.c:5:37:
/usr/include/bits/string3.h:110:33: warning: ‘void* __builtin___memcpy_chk(void*, const void*, long unsigned int, long unsigned int)’ writing 8 bytes into a region of size 3 overflows the destination [-Wstringop-overflow=]
   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
          ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This suffers from the same problem as the first case: the line
number of the offending call in bar() is missing.

In both cases the problem is compounded by the diagnostic, as
a result of folding, referring to __builtin___memcpy_chk while
the source code contains a call to strcpy.

I don't know nearly enough about the internals of the diagnostic
subsystem to tell how difficult it might be to change the output
to make it more readable.  David Malcolm is the expert on this
area so he might have an idea what it would take.

Martin

Reply via email to