This fixes PR52977 - for PCH to work with its pointer relocation code
we have to avoid dereferencing pointers to compute array lengths
in structures.  So we have to unfortunately keep duplicated info about
VECTOR_CST vector lengths.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-04-16  Richard Guenther  <rguent...@suse.de>

        PR middle-end/52977
        * tree.h (VECTOR_CST_NELTS): Adjust.
        (struct tree_vector): Add explicit length field.
        (make_vector_stat): Declare.
        (make_vector): Define.
        * tree.c (make_vector_stat): New function.
        (build_vector_stat): Use it.
        * tree-streamer-in.c (streamer_alloc_tree): Likewise.

Index: gcc/tree.c
===================================================================
*** gcc/tree.c  (revision 186491)
--- gcc/tree.c  (working copy)
*************** cst_and_fits_in_hwi (const_tree x)
*** 1315,1320 ****
--- 1315,1339 ----
          || TREE_INT_CST_HIGH (x) == -1);
  }
  
+ /* Build a newly constructed TREE_VEC node of length LEN.  */
+ 
+ tree
+ make_vector_stat (unsigned len MEM_STAT_DECL)
+ {
+   tree t;
+   unsigned length = (len - 1) * sizeof (tree) + sizeof (struct tree_vector);
+ 
+   record_node_allocation_statistics (VECTOR_CST, length);
+ 
+   t = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length 
PASS_MEM_STAT);
+ 
+   TREE_SET_CODE (t, VECTOR_CST);
+   TREE_CONSTANT (t) = 1;
+   VECTOR_CST_NELTS (t) = len;
+ 
+   return t;
+ }
+ 
  /* Return a new VECTOR_CST node whose type is TYPE and whose values
     are in a list pointed to by VALS.  */
  
*************** build_vector_stat (tree type, tree *vals
*** 1323,1338 ****
  {
    int over = 0;
    unsigned cnt = 0;
!   tree v;
!   int length = ((TYPE_VECTOR_SUBPARTS (type) - 1) * sizeof (tree)
!               + sizeof (struct tree_vector));
! 
!   record_node_allocation_statistics (VECTOR_CST, length);
! 
!   v = ggc_alloc_zone_cleared_tree_node_stat (&tree_zone, length 
PASS_MEM_STAT);
! 
!   TREE_SET_CODE (v, VECTOR_CST);
!   TREE_CONSTANT (v) = 1;
    TREE_TYPE (v) = type;
  
    /* Iterate through elements and check for overflow.  */
--- 1342,1348 ----
  {
    int over = 0;
    unsigned cnt = 0;
!   tree v = make_vector (TYPE_VECTOR_SUBPARTS (type));
    TREE_TYPE (v) = type;
  
    /* Iterate through elements and check for overflow.  */
Index: gcc/tree.h
===================================================================
*** gcc/tree.h  (revision 186491)
--- gcc/tree.h  (working copy)
*************** struct GTY(()) tree_complex {
*** 1534,1546 ****
  };
  
  /* In a VECTOR_CST node.  */
! #define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
  #define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
  #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
  
  struct GTY(()) tree_vector {
    struct tree_typed typed;
!   tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) 
elts[1];
  };
  
  #include "symtab.h"
--- 1534,1547 ----
  };
  
  /* In a VECTOR_CST node.  */
! #define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.length)
  #define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
  #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
  
  struct GTY(()) tree_vector {
    struct tree_typed typed;
!   unsigned length;
!   tree GTY ((length ("%h.length"))) elts[1];
  };
  
  #include "symtab.h"
*************** build_int_cstu (tree type, unsigned HOST
*** 4341,4346 ****
--- 4342,4349 ----
  extern tree build_int_cst (tree, HOST_WIDE_INT);
  extern tree build_int_cst_type (tree, HOST_WIDE_INT);
  extern tree build_int_cst_wide (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
+ extern tree make_vector_stat (unsigned MEM_STAT_DECL);
+ #define make_vector(n) make_vector_stat (n MEM_STAT_INFO)
  extern tree build_vector_stat (tree, tree * MEM_STAT_DECL);
  #define build_vector(t,v) build_vector_stat (t, v MEM_STAT_INFO)
  extern tree build_vector_from_ctor (tree, VEC(constructor_elt,gc) *);
Index: gcc/tree-streamer-in.c
===================================================================
*** gcc/tree-streamer-in.c      (revision 186491)
--- gcc/tree-streamer-in.c      (working copy)
*************** streamer_alloc_tree (struct lto_input_bl
*** 476,485 ****
    else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
      {
        HOST_WIDE_INT len = streamer_read_hwi (ib);
!       result = ggc_alloc_zone_cleared_tree_node ((len - 1) * sizeof (tree)
!                                                + sizeof (struct tree_vector),
!                                                &tree_zone);
!       TREE_SET_CODE (result, VECTOR_CST);
      }
    else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
      {
--- 476,482 ----
    else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
      {
        HOST_WIDE_INT len = streamer_read_hwi (ib);
!       result = make_vector (len);
      }
    else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
      {

Reply via email to