[gnu.gcc.bug] constant cache isn't constant in gcc 1.36

donn@CS.UTAH.EDU (Donn Seeley) (11/22/89)

I'm running GCC 1.36 on an HP 9000/370 running 4.3 BSD...

The effects of this bug are so difficult to reproduce that there isn't
much point in trying to present an example.  In our case, I found that
cc1 looped in reload() when trying to build a source file in the 'uw'
package.  During very tedious investigation with gdb I managed to trace
the bug all the way up to the front end, where I found that the size of
a structure was garbage.  This was odd since the structure size was
constant...  I discovered that build_int() was returning a trashed
integer_cst for the constant 6.  Any significant changes in the source
file seemed to cause the problem to vanish.

Despite the lack of an example, I think the fix should be persuasive
since the code in build_int() appears to be broken in an obvious way.
It looks like the cache for constants can allocate out of the temporary
obstack and thus create objects that may get stomped on when more than
one function is compiled.  Also, the cache only contains space for
positive values from 0 to 32 (why that range?) but never checks that
the constant is positive before using it as a subscript.  I made the
following change:

------------------------------------------------------------------------
*** /tmp/,RCSt1025128	Tue Nov 21 22:59:18 1989
--- stor-layout.c	Tue Nov 21 22:58:59 1989
***************
*** 209,221 ****
    register tree t;
    /* Type-size nodes already made for small sizes.  */
    static tree size_table[33];
  
!   if (v < 33 && size_table[v] != 0)
!     return size_table[v];
    t = build_int_2 (v, 0);
    TREE_TYPE (t) = sizetype;
!   if (v < 33)
!     size_table[v] = t;
    return t;
  }
  
--- 209,232 ----
    register tree t;
    /* Type-size nodes already made for small sizes.  */
    static tree size_table[33];
+   struct obstack *obstack;
+   extern struct obstack *expression_obstack;
+   extern struct obstack permanent_obstack;
  
!   if (v >= 0 && v < 33)
!     {
!       if (size_table[v] != 0)
! 	return size_table[v];
!       obstack = expression_obstack;
!       expression_obstack = &permanent_obstack;
!     }
    t = build_int_2 (v, 0);
    TREE_TYPE (t) = sizetype;
!   if (v >= 0 && v < 33)
!     {
!       size_table[v] = t;
!       expression_obstack = obstack;
!     }
    return t;
  }
  
------------------------------------------------------------------------

This isn't pretty but it works.  Our GCC now compiles 'uw' without
looping...

Donn Seeley    University of Utah CS Dept    donn@cs.utah.edu
40 46' 6"N 111 50' 34"W    (801) 581-5668    utah-cs!donn