diff mbox

Fix ICE with -Wodr (PR middle-end/61913)

Message ID 20140728084859.GB6889@atrey.karlin.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka July 28, 2014, 8:48 a.m. UTC
> On Mon, Jul 28, 2014 at 10:23:36AM +0200, Jan Hubicka wrote:
> > > On Sun, Jul 27, 2014 at 1:02 PM, Marek Polacek <polacek@redhat.com> wrote:
> > > > Wodr in common.opt was missing a Var, which means:
> > > > 1) we ICE with -Wodr, since -Wodr isn't handled in opts.c;
> > > > 2) -Wno-odr wouldn't work.
> > > > Thus fixed.  I'd think this doesn't need a testcase...
> > > >
> > > > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > > 
> > > Ok.  Does this mean we don't have a -Wodr testcase?
> > 
> > We ICE at -Wno-odr (thanks for fixing it! I was somewhat puzzled by fact
> > that I need to declare var that is not needed at all).
> > 
> > But there is no -Wodr testcase as I do not know how to match warnings at LTO
> > time. If there is a way, I will add one.
> 
> Heh, I was just trying to create some testcase for -Wodr, but failed.
> pr60720_0.c testcase says:
> 
> /* ???  lto.exp does not allow to scan for
>    :1:12: warning: type of 'x' does not match original declaration
>     extern int x[];
>                ^
>    :1:5: note: previously declared here
>     int x;
>         ^  */

This is not ODR warning however, it is declaration mismatch.  Yes, lack of
scanning machinery is sad ;( BTW these type of warnings tends ot be
uninformative in the sense:

>    :1:5: warning: type of 'x' does not match original declaration
>     foo x;
>                ^
>    :1:5: note: previously declared here
>     foo x;

That is caused by different defines or typedefs earlier in the file.  This is
uninformative enough so users tends to ignore the warning as obvious GCC bug.
I tested attached patch that adds unit name into TRANSLATION_UNIT_DECL. It adds
main source file, perhaps output object file name would make more sense, but I
did not find global var for that.

Then I use it as follows:
  /* See if we have info about the translation unit.  It may not be around
     if types was already merged.   */
  while (TREE_CODE (name) != TRANSLATION_UNIT_DECL)
    name = TYPE_P (name) ? TYPE_CONTEXT (name) : DECL_CONTEXT (name);
  while (TREE_CODE (name1) != TRANSLATION_UNIT_DECL)
    name1 = TYPE_P (name1) ? TYPE_CONTEXT (name1) : DECL_CONTEXT (name1);
  name = DECL_NAME (name);
  name1 = DECL_NAME (name1);
  if (name != name1 && name && name1)
    inform (UNKNOWN_LOCATION, "Conflicting compilation units: %s and %s",
            IDENTIFIER_POINTER (name),
            IDENTIFIER_POINTER (name1));

We may want to have some sort of convenience wrapper for this.

Because the type merging ignores TRANSLATION_UNIT_DECL, it may end up being
wrong.  In the contextes we use it however - that we have unmerged duplicated
decls or unmerged duplicated types, it however usually points to two different
files that are the origins of the trees that is good enough.
diff mbox

Patch

Index: tree.c
===================================================================
--- tree.c	(revision 212987)
+++ tree.c	(working copy)
@@ -4539,6 +4540,8 @@  build_translation_unit_decl (tree name)
   tree tu = build_decl (UNKNOWN_LOCATION, TRANSLATION_UNIT_DECL,
 			name, NULL_TREE);
   TRANSLATION_UNIT_LANGUAGE (tu) = lang_hooks.name;
+  if (main_input_filename)
+    DECL_NAME (tu) = get_identifier (main_input_filename);
   vec_safe_push (all_translation_units, tu);
   return tu;
 }