This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug lto/51573] [4.7 Regression] ICE (segfault) in lto_varpool_encoder_encode_initializer_p


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51573

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dnovillo at gcc dot
                   |                            |gnu.org, jason at gcc dot
                   |                            |gnu.org
             Blocks|                            |48508, 48437

--- Comment #5 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-12-16 10:21:16 UTC ---
Because of the way C++ treats things (look at PR48508) it is impossible to
move fixing PRs 48508 and 48437 to the point where we handle decl merging.
Thus, while

Index: gcc/lto-symtab.c
===================================================================
--- gcc/lto-symtab.c    (revision 182398)
+++ gcc/lto-symtab.c    (working copy)
@@ -785,6 +785,12 @@ lto_symtab_prevailing_decl (tree decl)
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_ABSTRACT (decl))
     return decl;

+  /* Extern decls with function context should not be merged, they
+     appear in BLOCK_VARS.  */
+  if (DECL_EXTERNAL (decl)
+      && decl_function_context (decl))
+    return decl;
+
   /* Ensure DECL_ASSEMBLER_NAME will not set assembler name.  */
   gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));

Index: gcc/lto/lto.c
===================================================================
--- gcc/lto/lto.c       (revision 182398)
+++ gcc/lto/lto.c       (working copy)
@@ -867,9 +867,13 @@ uniquify_nodes (struct data_in *data_in,
       if (t == NULL_TREE)
        continue;

-      if (TREE_CODE (t) == VAR_DECL)
+      if (TREE_CODE (t) == VAR_DECL
+         && (!DECL_EXTERNAL (t)
+             || !decl_function_context (t)))
        lto_register_var_decl_in_symtab (data_in, t);
-      else if (TREE_CODE (t) == FUNCTION_DECL && !DECL_BUILT_IN (t))
+      else if (TREE_CODE (t) == FUNCTION_DECL && !DECL_BUILT_IN (t)
+              && (!DECL_EXTERNAL (t)
+                  || !decl_function_context (t)))
        lto_register_function_decl_in_symtab (data_in, t);
       else if (TYPE_P (t) && !TYPE_CANONICAL (t))
        TYPE_CANONICAL (t) = gimple_register_canonical_type (t);


works great for C it does not work for C++ at all because in

static void
bar (void)
{
  extern void foo (int);
  foo (0);
}

the function-local extern declaration of 'foo' has a toplevel DECL_CONTEXT.

Thus the only way I see to fix this bug is to introduce either a new
streaming hook or add an argument to the stream_write_tree that
indicates whether the actual tree should be streamed by reference,
not affecting its siblings.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]