Bug 54962 - Strange-looking diagnostics from diagnostic_report_current_module() from warnings emitted during LTO
Summary: Strange-looking diagnostics from diagnostic_report_current_module() from warn...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on: 65536
Blocks:
  Show dependency treegraph
 
Reported: 2012-10-17 20:30 UTC by Dave Malcolm
Modified: 2019-11-20 05:14 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-10-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Malcolm 2012-10-17 20:30:22 UTC
I'm working on a whole-program static analyzer that runs from a gcc plugin during lto1 when invoked via
  -flto -flto-partition=none
as an IPA_PASS registered before "whole-program".

I'm currently emitting errors using error_at() with inform() to give extra information on the (possibly interprocedural) execution path taken to reach the error.  This works, but leads to unusual-looking output.

For example, with:
  $ gcc -flto -flto-partition=none [...various plugin args...] input-f.c input-g.c input-h.c

my code detects a double-free involving an execution path between input-h.c and input-g.c and calls
  error_at("double-free of r")
on a location_t from input-h.c and gets this strange output on stderr:

  In file included from test.h:1:0,
                   from /usr/include/stdlib.h:489,
                   from input-f.c:14,
                   from :3:
  input-h.c:13:9: error: double-free of r

it then calls
    inform("q passed to free()")
on a location_t from input-g.c (to show the location of the 1st free call) and gets this on stderr:

  In file included from test.h:1:0,
                   from /usr/include/stdlib.h:489,
                   from input-f.c:14,
                   from :3:
  input-g.c:11:7: note: q passed to free()

In both cases, the "In file included from " hierarchies look bogus: the files are being directly compiled, not included.

Debugging, it comes from gcc/diagnostic.c:diagnostic_report_current_module() where I see this code:

  275	  if (map && diagnostic_last_module_changed (context, map))
  276	    {
  277	      diagnostic_set_last_module (context, map);
  278	      if (! MAIN_FILE_P (map))
  279		{
  280		  map = INCLUDED_FROM (line_table, map);
  281		  if (context->show_column)
  282		    pp_verbatim (context->printer,
  283				 "In file included from %s:%d:%d",
  284				 LINEMAP_FILE (map),
  285				 LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map));
  286		  else
  287		    pp_verbatim (context->printer,
  288				 "In file included from %s:%d",
  289				 LINEMAP_FILE (map), LAST_SOURCE_LINE (map));
  290		  while (! MAIN_FILE_P (map))
  291		    {
  292		      map = INCLUDED_FROM (line_table, map);

This code appears to assume (via MAIN_FILE_P) that there is a concept of a main file, and that everything else is included from it.  However in the context of diagnostics emitted during LTO it's not clear that this concept makes sense (or maybe I'm missing something?  I also wonder if by attempting to issue diagnostics from within lto1 if I'm in unexplored territory here?)

This is called by default_tree_diagnostic_starter FWIW; perhaps lto1 needs its own implementation of this?
Comment 1 Manuel López-Ibáñez 2012-10-17 20:43:51 UTC
Where doe the line_maps that LTO use come from? Perhaps they are not saved/restored correctly?
Comment 2 Richard Biener 2012-10-18 09:55:45 UTC
(In reply to comment #0)
>   290          while (! MAIN_FILE_P (map))
>   291            {
>   292              map = INCLUDED_FROM (line_table, map);
> 
> This code appears to assume (via MAIN_FILE_P) that there is a concept of a main
> file, and that everything else is included from it.  However in the context of
> diagnostics emitted during LTO it's not clear that this concept makes sense (or
> maybe I'm missing something?  I also wonder if by attempting to issue
> diagnostics from within lto1 if I'm in unexplored territory here?)

You definitely are, if you are expecting everything to work just fine ;)

> This is called by default_tree_diagnostic_starter FWIW; perhaps lto1 needs its
> own implementation of this?

Maybe yes.  LTO should print the "main" file as well (so it doesn't have
a MAIN_FILE_P), but not as included-from but in some other way.

Patches welcome ;)
Comment 3 Manuel López-Ibáñez 2012-10-18 10:39:08 UTC
(In reply to comment #2)
> > This is called by default_tree_diagnostic_starter FWIW; perhaps lto1 needs its
> > own implementation of this?
> 
> Maybe yes.  LTO should print the "main" file as well (so it doesn't have
> a MAIN_FILE_P), but not as included-from but in some other way.
> 

How does the line_map works in LTO? Is it saved and restored or re-build from scratch?
Comment 4 Richard Biener 2012-10-18 10:40:34 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > > This is called by default_tree_diagnostic_starter FWIW; perhaps lto1 needs its
> > > own implementation of this?
> > 
> > Maybe yes.  LTO should print the "main" file as well (so it doesn't have
> > a MAIN_FILE_P), but not as included-from but in some other way.
> > 
> 
> How does the line_map works in LTO? Is it saved and restored or re-build from
> scratch?

We stream the expanded location and allocate new line-map entries at LTO
read time.
Comment 5 Manuel López-Ibáñez 2012-10-18 11:38:33 UTC
(In reply to comment #4)
> 
> We stream the expanded location and allocate new line-map entries at LTO
> read time.

Where? 

I guess this precludes any knowledge of what is included from where and for sure no tracking of macro expansion, but it still doesn't explain why MAIN_FILE_P and INCLUDED_FROM do not work reliably. They should be true for every map and return NULL, respectively. That seems like a bug.
Comment 6 Manuel López-Ibáñez 2015-03-24 22:13:53 UTC
(In reply to Dave Malcolm from comment #0)
> In both cases, the "In file included from " hierarchies look bogus: the
> files are being directly compiled, not included.
> 

Please try the patch in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65536#c21
Comment 7 Manuel López-Ibáñez 2015-03-24 22:20:41 UTC
(In reply to Manuel López-Ibáñez from comment #6)
> (In reply to Dave Malcolm from comment #0)
> > In both cases, the "In file included from " hierarchies look bogus: the
> > files are being directly compiled, not included.
> > 
> 
> Please try the patch in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65536#c21

You need also the libcpp hunks from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65536#c18