[debug-early] fix problem with C_TYPE_INCOMPLETE_VARS and TYPE_VFIELD overloading
diff mbox

Message ID 553AAD0D.5040206@redhat.com
State New
Headers show

Commit Message

Aldy Hernandez April 24, 2015, 8:52 p.m. UTC
In the debug-early work we call dwarf2out early from 
rest_of_decl_compilation.  Dwarf2out, via 
gen_struct_or_union_type_die(), will eventually look at TYPE_VFIELD, 
which is currently being overloaded by the C front-end to keep 
incomplete variables.

Nobody should be looking at the type too in depth if it's incomplete, 
but in this case, the type has just been laid out (layout_decl) so it's 
considered complete, just as we're about to iterate through 
C_TYPE_INCOMPLETE_VARS and fix things up.

To fix my dwarf problem, I've just cached C_TYPE_INCOMPLETE_VARS and 
immediately clear it, as it was going to be cleared after anyhow.

Attached is what I'm committing to the branch, but ideally y'all^Wyall 
front-end folks should use some language specific node.  Nothing was 
obvious in tree-core.h, as most front-end specific things are flags 
(booleans), so I've left this as an exercise to the front-end groupie. 
That being said, if you violently oppose this solution, I'd be more than 
happy to entertain another (hopefully simple) approach.

Aldy

p.s. I wonder how many things are being overloaded by the front-end that 
are being looked at by dwarf2out incorrectly.  Well, nothing that 
triggers a gdb regression....
commit 0fa38f203619300ed1ea92418bc6dbabd1115ac9
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Fri Apr 24 13:41:36 2015 -0700

    Cache and clear C_TYPE_INCOMPLETE_VARS before iterating through its
    members to avoid an overload problem within dwarf2out.

Comments

Richard Henderson April 24, 2015, 11:27 p.m. UTC | #1
On 04/24/2015 10:52 AM, Aldy Hernandez wrote:
> In the debug-early work we call dwarf2out early from rest_of_decl_compilation. 
> Dwarf2out, via gen_struct_or_union_type_die(), will eventually look at
> TYPE_VFIELD, which is currently being overloaded by the C front-end to keep
> incomplete variables.
> 
> Nobody should be looking at the type too in depth if it's incomplete, but in
> this case, the type has just been laid out (layout_decl) so it's considered
> complete, just as we're about to iterate through C_TYPE_INCOMPLETE_VARS and fix
> things up.
> 
> To fix my dwarf problem, I've just cached C_TYPE_INCOMPLETE_VARS and
> immediately clear it, as it was going to be cleared after anyhow.

The patch is ok.


r~

> 
> Attached is what I'm committing to the branch, but ideally y'all^Wyall
> front-end folks should use some language specific node.  Nothing was obvious in
> tree-core.h, as most front-end specific things are flags (booleans), so I've
> left this as an exercise to the front-end groupie. That being said, if you
> violently oppose this solution, I'd be more than happy to entertain another
> (hopefully simple) approach.
> 
> Aldy
> 
> p.s. I wonder how many things are being overloaded by the front-end that are
> being looked at by dwarf2out incorrectly.  Well, nothing that triggers a gdb
> regression....

Patch
diff mbox

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 846e13b..688c055 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -7827,10 +7827,18 @@  finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
     }
 
   /* If this structure or union completes the type of any previous
-     variable declaration, lay it out and output its rtl.  */
-  for (x = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
-       x;
-       x = TREE_CHAIN (x))
+     variable declaration, lay it out and output its rtl.
+
+     Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used
+     in dwarf2out via rest_of_decl_compilation below and means
+     something totally different.  Since we will be clearing
+     C_TYPE_INCOMPLETE_VARS shortly after we iterate through them,
+     clear it ahead of time and avoid problems in dwarf2out.  Ideally,
+     C_TYPE_INCOMPLETE_VARS should use some language specific
+     node.  */
+  tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
+  C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
+  for (x = incomplete_vars; x; x = TREE_CHAIN (x))
     {
       tree decl = TREE_VALUE (x);
       if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
@@ -7843,7 +7851,6 @@  finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 	  rest_of_decl_compilation (decl, toplevel, 0);
 	}
     }
-  C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
 
   /* Update type location to the one of the definition, instead of e.g.
      a forward declaration.  */