[PATCH] RFC: On-demand locations within string-literals

Martin Sebor msebor@gmail.com
Sat Jul 23 21:36:00 GMT 2016


On 07/08/2016 03:49 PM, David Malcolm wrote:
> This patch implements precise tracking of source locations for the
> individual chars within string literals, so that we can e.g. underline
> specific ranges in -Wformat diagnostics.
...
> Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.
>
> Thoughts?

I applied the patch to my -Wformat-length branch and managed to
get it to work in the sprintf-length pass in the middle end, but
I'm not sure I did it right (I suspect not, or at least not the
way it should be done).  I couldn't find other places where the
bits it depends on are used (I copied bits and pieces of the code
I used from the C front end until it all fell into place ).  It
would be great if there was a tutorial on how to plug it in where
it isn't used yet (as in the middle end).  For example, how do
I determine what CLK_XXX constant I should pass to the
cpp_create_reader() function in the middle end?

I ran my tests with the patch and while it handled a good number
of test cases it eventually crashed.  A test case for the ICE is
attached though it needs my -Wformat-length patch to trigger it.
You may be able to tell what's wrong from the debugger context
(included in the test case).  If not, you may be able to
reproduce it by applying my latest patch and hacking the three
argument overload of location_from_offset() the way I did (in
the xyz.i comment).  Or I can send you my latest patch with all
this in place.

Beyond that, the range normally works fine, except when macros
are involved like they are in my tests.  You can see the effect
in the range.out file.  (This works without your patch but it
could very well be because I didn't set it up right.)

That's all I have for now.

Martin

-------------- next part --------------
# 1 "/src/gcc-49905/gcc/testsuite/gcc.dg/format/c99-sprintf-length-1.c"

char buffer [8];
extern char *ptr;

void f (__builtin_va_list va)
{
  __builtin_sprintf (buffer + sizeof buffer, "%c", 0);
}

/*
(gdb) r
Starting program: /build/gcc-49905/gcc/cc1 -fpreprocessed xyz.i -quiet -dumpbase xyz.i -mtune=generic -march=x86-64 -auxbase xyz -Wformat=1 -Wformat-length=1 -o xyz.s

Breakpoint 1, location_from_offset (loc=2147483652, offset=1, length=2)
    at /src/gcc-49905/gcc/gimple-ssa-sprintf.c:369
369	    = cpp_create_reader (CLK_GNUC11, ident_hash, line_table);
(gdb) l
364	static location_t
365	location_from_offset (location_t loc, int offset, int length)
366	{
367	#if 1
368	  static struct cpp_reader* parse_in
369	    = cpp_create_reader (CLK_GNUC11, ident_hash, line_table);
370	
371	  static string_concat_db *g_string_concat_db
372	    = new (ggc_alloc <string_concat_db> ()) string_concat_db ();
373	
(gdb) l
374	  source_range range;
375	  if (get_source_range_for_substring (parse_in, g_string_concat_db, loc,
376					      offset, offset + length, &range))
377	    return make_location (range.m_start, range.m_start, range.m_finish);
378	  return loc;
379	#else
(gdb) c
/src/gcc-49905/gcc/testsuite/gcc.dg/format/c99-sprintf-length-1.c: In function â??:
/src/gcc-49905/gcc/testsuite/gcc.dg/format/c99-sprintf-length-1.c:5:6: internal compiler error: in get_substring_ranges_for_loc, at input.c:1310
    and avoid exercising any of the others.  The buffer and objsize macros
      ^
0x1921136 get_substring_ranges_for_loc
	/src/gcc-49905/gcc/input.c:1310
0x19212cc get_source_range_for_substring(cpp_reader*, string_concat_db*, unsigned int, int, int, source_range*)
	/src/gcc-49905/gcc/input.c:1354
0x17eb1ae location_from_offset
	/src/gcc-49905/gcc/gimple-ssa-sprintf.c:375
0x17ed220 compute_format_length
	/src/gcc-49905/gcc/gimple-ssa-sprintf.c:1343
0x17edf4c pass_sprintf_length::compute_format_length(pass_sprintf_length::call_info const&, format_result*)
	/src/gcc-49905/gcc/gimple-ssa-sprintf.c:1880
0x17ee780 pass_sprintf_length::handle_gimple_call(gimple_stmt_iterator)
	/src/gcc-49905/gcc/gimple-ssa-sprintf.c:2122
0x17ee8cf pass_sprintf_length::execute(function*)
	/src/gcc-49905/gcc/gimple-ssa-sprintf.c:2153
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
[Inferior 1 (process 23446) exited with code 04]


 */
-------------- next part --------------
$ cat xyz.c && /build/gcc-49905/gcc/xgcc -B/build/gcc-49905/gcc -Wformat -Wformat-length=1 -S xyz.c
char d[2];

#define P(n, f) __builtin_vsprintf (d + sizeof d - n, f, va)

void f (__builtin_va_list va)
{
   __builtin_vsprintf (d + sizeof d - 2, "%#3x", va);
  P (2, "%#3x");
}
xyz.c: In function â??fâ??:
xyz.c:7:42: warning: â??%#3xâ?? directive writing between 3 and 10 bytes into a region of size 2 [-Wformat-length=]
    __builtin_vsprintf (d + sizeof d - 2, "%#3x", va);
                                          ^~~~~~
xyz.c:7:42: note: using the range [â??1uâ??, â??2147483648uâ??] for directive argument
xyz.c:7:4: note: format output between 4 and 11 bytes into a destination of size 2
    __builtin_vsprintf (d + sizeof d - 2, "%#3x", va);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xyz.c:8:9: warning: â??%#3xâ?? directive writing between 3 and 10 bytes into a region of size 2 [-Wformat-length=]
   P (2, "%#3x");
         ^
xyz.c:3:55: note: in definition of macro â??Pâ??
 #define P(n, f) __builtin_vsprintf (d + sizeof d - n, f, va)
                                                       ^
xyz.c:8:9: note: using the range [â??1uâ??, â??2147483648uâ??] for directive argument
   P (2, "%#3x");
         ^
xyz.c:3:55: note: in definition of macro â??Pâ??
 #define P(n, f) __builtin_vsprintf (d + sizeof d - n, f, va)
                                                       ^
xyz.c:3:17: note: format output between 4 and 11 bytes into a destination of size 2
 #define P(n, f) __builtin_vsprintf (d + sizeof d - n, f, va)
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xyz.c:8:3: note: in expansion of macro â??Pâ??
   P (2, "%#3x");
   ^


More information about the Gcc-patches mailing list