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

--- Comment #25 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-07-04 
11:26:55 UTC ---
Or the insn_data initializer does not properly point to the operand_data
initializer (maybe that is non-existent or the magic LTO error_mark_node
and we fold that in a wrong way - VOIDmode happens to be zero after all...).

See the special code in get_base_constructor in gimple-fold.c:

/* See if we can find constructor defining value of BASE.
   When we know the consructor with constant offset (such as
   base is array[40] and we do know constructor of array), then
   BIT_OFFSET is adjusted accordingly.

   As a special case, return error_mark_node when constructor
   is not explicitly available, but it is known to be zero
   such as 'static const int a;'.  */
static tree
get_base_constructor (tree base, HOST_WIDE_INT *bit_offset,
                      tree (*valueize)(tree))
...
  switch (TREE_CODE (base))
    {
    case VAR_DECL:
      if (!const_value_known_p (base))
        return NULL_TREE;

      /* Fallthru.  */
    case CONST_DECL:
      if (!DECL_INITIAL (base)
          && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
        return error_mark_node;
      return DECL_INITIAL (base);

and lto-streamer-out.c:

/* Write a physical representation of tree node EXPR to output block
   OB.  If REF_P is true, the leaves of EXPR are emitted as references
   via lto_output_tree_ref.  IX is the index into the streamer cache
   where EXPR is stored.  */

static void
lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
{
...
      /* Handle DECL_INITIAL for symbols.  */
      tree initial = DECL_INITIAL (expr);
      if (TREE_CODE (expr) == VAR_DECL
          && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
          && initial)
        {
          lto_varpool_encoder_t varpool_encoder;
          struct varpool_node *vnode;

          varpool_encoder = ob->decl_state->varpool_node_encoder;
          vnode = varpool_get_node (expr);
          if (!vnode
              || !lto_varpool_encoder_encode_initializer_p (varpool_encoder,
                                                            vnode))
            initial = error_mark_node;


So, does

Index: gimple-fold.c
===================================================================
--- gimple-fold.c       (revision 189251)
+++ gimple-fold.c       (working copy)
@@ -2713,6 +2713,8 @@ get_base_constructor (tree base, HOST_WI
       if (!DECL_INITIAL (base)
          && (TREE_STATIC (base) || DECL_EXTERNAL (base)))
         return error_mark_node;
+      if (DECL_INITIAL (base) == error_mark_node)
+       return NULL_TREE;
       return DECL_INITIAL (base);

     case ARRAY_REF:

fix it?

Reply via email to