From: rfg@segfault.UUCP
Subject: Re: bug in cc1plus (dwarfout.c)
Reply-To: lupine!segfault!rfg@uunet.uu.net
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sun, 26 Jul 1992 22:11:07 GMT

Hugues,

Thank you for your bug report noting the new segfault(s) when generating
DWARF debugging information using g++ 2.2.2 targeted for i486-svr4.

I narrowed down your bug report (which was based on the gperf sources) to
the following code:

---------------------------------------------------------------------------
struct Gen_Perf {
	int max_hash_value;
	int operator ()();
};

int
Gen_Perf::operator() (void)
{
  int buffer[max_hash_value];
  return 0;
}
---------------------------------------------------------------------------

This code actually illustrates two separate bugs in the g++ front end.

First, the g++ front end is failing to wrap variable array sizes in
SAVE_EXPRs as required by dwarfout.c.   This adjustment was made to
the GCC front-end quite a long time ago:

---------------------------------------------------------------------------
Sun Sep 23 00:05:49 1990  Richard Stallman  (rms at mole.ai.mit.edu)

        * c-decl.c (grokdeclarator): Put var array bound in save_expr.
---------------------------------------------------------------------------

Apparently, the maintainers of the g++ front end simply never followed
suit.

The patches below for cp-decl.c seem to rectify the problem.

Second, it appears that the g++ front-end is failing to attach a proper
list of formal argument types to METHOD_TYPE nodes in some cases.  In
particular, while the g++ front end normally creates METHOD_TYPEs for
all non-static member function (and operators) and gives these types
at least one formal argument type (corresponding to the hidden `this'
parameter) this general rule appears to be violated the the example
given above... the METHOD_TYPE node generated for the member operator
appears to have no formal argument types attach to it, for reasons which
not at all apparent (to me at least).

This second g++ bug ultimately leads to a segfault in dwarfout.c because
the g++ front-end is not playing by the rules.  (Garbage in, garbage out.)

This second g++ front-end bug will ultimately have to be fixed by the
g++ maintainers, however I have also provided a temporary workaround
for this problem below.

Please continue to send me examples of cases where using the -g option
with g++ under svr4 causes compiler crashes.  They are most helpful.

// rfg


P.S.  Please note that I do not maintain the g++ front-end, so I cannot
say when (or even if) these g++ bugs will ever be fixed.


*** cp-decl.c-	Wed Jun 10 21:14:00 1992
--- cp-decl.c	Sun Jul 26 15:32:49 1992
*************** grokdeclarator (declarator, declspecs, d
*** 6216,6220 ****
    enum tree_code innermost_code = ERROR_MARK;
    int bitfield = 0;
!   int variable_size = 0;
    /* Set this to error_mark_node for FIELD_DECLs we could not handle properly.
       All FIELD_DECLs we build here have `init' put into their DECL_INITIAL.  */
--- 6216,6220 ----
    enum tree_code innermost_code = ERROR_MARK;
    int bitfield = 0;
!   int size_varies = 0;
    /* Set this to error_mark_node for FIELD_DECLs we could not handle properly.
       All FIELD_DECLs we build here have `init' put into their DECL_INITIAL.  */
*************** grokdeclarator (declarator, declspecs, d
*** 7086,7089 ****
--- 7086,7093 ----
  		  dont_grok_size:
  		    itype = build_binary_op (MINUS_EXPR, size, integer_one_node);
+ 		    /* Make sure the array size remains visibly nonconstant
+ 		       even if it is (eg) a const variable with known value.  */
+ 		    size_varies = 1;
+ 		    itype = variable_size (itype);
  		    itype = build_index_type (itype);
  		  }
*** dwarfout.c-	Sun Jul 26 14:19:53 1992
--- dwarfout.c	Sun Jul 26 15:42:38 1992
*************** output_decl (decl, containing_scope)
*** 3825,3829 ****
  
  	  if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
! 	    arg_decls = TREE_CHAIN (arg_decls);
  
  	  {
--- 3825,3829 ----
  
  	  if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
! 	    arg_decls = arg_decls ? TREE_CHAIN (arg_decls) : NULL_TREE;
  
  	  {

Newsgroups: gnu.g++.bug