g++ memory bug.

Mike Stump mrs@wrs.com
Thu Jan 7 21:18:00 GMT 1999


> Date: Thu, 07 Jan 1999 11:18:20 +0100
> From: Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>

> > g++ -v
> Reading specs from /u/corse/2/robotvis/gnu/bin/egcs/lib/gcc-lib/sparc-sun-solaris2.6/egcs-2.92.20/specs
> gcc version egcs-2.92.20 19981109 (gcc2 ss-980609 experimental)

> > g++ -ftemplate-depth-100 -O4 -DM2 MemBug.C
> g++: Internal compiler error: program cc1plus got fatal signal 11

Interesting, I get:

    t.cc:5: virtual memory exhausted

on my solaris 2.5.1 sparc box, so I think one aspect of this is
better, andway, if you woul just compile with around 226 TB, it would
compile just fine.  :-)

I was using:

gcc version egcs-2.92.34 19990105 (gcc2 ss-980609 experimental)

You can compile this with -fno-default-inline just fine.

I researched it out and it is an interesting intersection of
semantics.  inline means in gcc to always inline, reguardless of size,
and the default for members is to treat them as if inline was
specified.  Something here is wrong.  We can either default
flag_default_inline to off, and let the user say -fdefault-inline, if
they want it (the other way that the function will be inlined, is if
they say -O4, which I think is reasonable), or we can put a artificial
limit on the size of a function to inline even when they are `inline'.
The code produced differs some between these two solutions.  In the
first case, we wind up with lots of little functions that have 32
lines each, in the second case, we have two functions, one with 256
lines, the second with 4096 lines.  I think random people with random
code that compile with -O won't line the first solution (why wasn't
the simple 1 line member function defined inside the class inlined?).

Below are the two patches, select only one.  I am not really sure
which one I prefer.  Comments?

Concerns: not much testing, do we loose by not saying DECL_INLINE in
the first solution?

Thu Jan  7 20:33:19 1999  Mike Stump  <mrs@wrs.com>

	* invoke.texi (C++ Dialect Options): Default is to not treat
	members as `inline'.

Thu Jan  7 20:33:19 1999  Mike Stump  <mrs@wrs.com>

	* decl2.c (flag_default_inline): Default is to not treat
	members as `inline'.

Doing diffs in gcc/invoke.texi.~1~:
*** gcc/invoke.texi.~1~	Mon Jan  4 18:24:59 1999
--- gcc/invoke.texi	Thu Jan  7 20:31:35 1999
*************** In addition, these optimization, warning
*** 1155,1162 ****
  have meanings only for C++ programs:
  
  @table @code
! @item -fno-default-inline
! Do not assume @samp{inline} for functions defined inside a class scope.
  @xref{Optimize Options,,Options That Control Optimization}.  Note that these
  functions will have linkage like inline functions; they just won't be
  inlined by default.
--- 1155,1162 ----
  have meanings only for C++ programs:
  
  @table @code
! @item -fdefault-inline
! Do assume @samp{inline} for functions defined inside a class scope.
  @xref{Optimize Options,,Options That Control Optimization}.  Note that these
  functions will have linkage like inline functions; they just won't be
  inlined by default.
--------------
Doing diffs in gcc/cp/decl2.c.~1~:
*** gcc/cp/decl2.c.~1~	Tue Dec 15 14:13:47 1998
--- gcc/cp/decl2.c	Thu Jan  7 20:30:13 1999
*************** int flag_handle_signatures;
*** 363,369 ****
  /* Nonzero means that member functions defined in class scope are
     inline by default.  */
  
! int flag_default_inline = 1;
  
  /* Controls whether compiler generates 'type descriptor' that give
     run-time type information.  */
--- 363,369 ----
  /* Nonzero means that member functions defined in class scope are
     inline by default.  */
  
! int flag_default_inline = 0;
  
  /* Controls whether compiler generates 'type descriptor' that give
     run-time type information.  */
--------------

Thu Jan  7 20:33:19 1999  Mike Stump  <mrs@wrs.com>

	* integrate.c (function_cannot_inline_p): Don't inline unreasonably
	large functions, even if we say `inline'.

Doing diffs in gcc/integrate.c.~1~:
*** gcc/integrate.c.~1~	Tue Dec 15 14:13:39 1998
--- gcc/integrate.c	Thu Jan  7 20:57:05 1999
*************** function_cannot_inline_p (fndecl)
*** 120,125 ****
--- 120,129 ----
    register tree parms;
    rtx result;
  
+   /* We place a limit on even functions marked as inline.  */
+   if (DECL_INLINE (fndecl))
+     max_insns *= 100;
+ 
    /* No inlines with varargs.  */
    if ((last && TREE_VALUE (last) != void_type_node)
        || current_function_varargs)
*************** function_cannot_inline_p (fndecl)
*** 135,141 ****
      return current_function_cannot_inline;
  
    /* If its not even close, don't even look.  */
!   if (!DECL_INLINE (fndecl) && get_max_uid () > 3 * max_insns)
      return "function too large to be inline";
  
  #if 0
--- 139,145 ----
      return current_function_cannot_inline;
  
    /* If its not even close, don't even look.  */
!   if (get_max_uid () > 3 * max_insns)
      return "function too large to be inline";
  
  #if 0
*************** function_cannot_inline_p (fndecl)
*** 169,175 ****
  	return "function with transparent unit parameter cannot be inline";
      }
  
!   if (!DECL_INLINE (fndecl) && get_max_uid () > max_insns)
      {
        for (ninsns = 0, insn = get_first_nonparm_insn ();
  	   insn && ninsns < max_insns;
--- 173,179 ----
  	return "function with transparent unit parameter cannot be inline";
      }
  
!   if (get_max_uid () > max_insns)
      {
        for (ninsns = 0, insn = get_first_nonparm_insn ();
  	   insn && ninsns < max_insns;
--------------



More information about the Gcc-patches mailing list