[gnu.g++.bug] segv building tests/tString.cc

raeburn@ATHENA.MIT.EDU (Ken Raeburn) (09/14/89)

I'm getting an abort from cc1plus building tests/tString.cc.  The
output:

% g++ -v -g -O -fstrength-reduce -I/site/raeburn/libg++ -c tString.cc
gcc version 1.35.99
 /multics/site/raeburn/g++/cpp -+ -v -I/multics/site/raeburn/libg++/g++-include-I/site/raeburn/libg++ -undef -D__GNUC__ -Dvax -Dunix -D__vax__ -D__unix__ -D__OPTIMIZE__ tString.cc /usr/tmp/cc015202.cpp
GNU CPP version 1.35.99
 /multics/site/raeburn/g++/cc1plus /usr/tmp/cc015202.cpp -fcombine-regs -fstrength-reduce -quiet -dumpbase tString.cc -fstrength-reduce -g -O -version -o /usr/tmp/cc015202.s
GNU C++ version 1.36.0- (based on GCC 1.35.98+) (vax) compiled by GNU C version 1.35.99.
default target switches:
/mit/gnu/vaxbin/gcc: Program cc1plus got fatal signal 4.
Exit 1               g++ -v -g -O -fstrength-reduce -I/site/raeburn/libg++ -c tString.cc
%

My script "g++" runs the 1.35.99 "gcc" (which we've got installed)
with all the -I, -B, -L arguments I need to get at the new g++ (which
isn't installed).  (This version was compiled with 1.35.99, but uses
sources from 1.35.98.)

A stack trace with gdb:

(gdb) bt
#0  0x851ce in abort ()
#1  0x45436 in emit_move_insn (x=(rtx) 0x1fc0e8, y=(rtx) 0x938ac) (expr.c line 1093)
#2  0x5077b in copy_to_reg (x=(rtx) 0x938ac) (explow.c line 397)
#3  0x5062e in memory_address (mode=SImode, x=(rtx) 0x1fc0dc) (explow.c line 303)
#4  0x5b5cc in copy_rtx_and_substitute (orig=(rtx) 0x19a970) (integrate.c line 1351)
#5  0x5b8b1 in copy_rtx_and_substitute (orig=(rtx) 0x19a95c) (integrate.c line 1475)
#6  0x5af9c in expand_inline_function (fndecl=(tree) 0x13e84c, parms=(tree) 0x1fa408, target=(rtx) 0x1fbd20, ignore=0, type=(tree) 0x125480, structure_value_addr=(rtx) 0x1fbd14) (integrate.c line 1013)
#7  0x486a7 in expand_call (exp=(tree) 0x95528, target=(rtx) 0x1fbd20, ignore=0, modifier=EXPAND_NORMAL) (expr.c line 4119)
#8  0x478da in expand_expr (exp=(tree) 0x954b8, target=(rtx) 0x0, tmode=VOIDmode, modifier=EXPAND_CONST_ADDRESS) (expr.c line 3190)
#9  0x47ad3 in expand_expr (exp=(tree) 0x954d8, target=(rtx) 0x0, tmode=SImode,modifier=EXPAND_NORMAL) (expr.c line 3302)
#10 0x5aaf3 in expand_inline_function (fndecl=(tree) 0x133b54, parms=(tree) 0x1fa4c8, target=(rtx) 0x0, ignore=1, type=(tree) 0x99ea8, structure_value_addr=(rtx) 0x0) (integrate.c line 716)
#11 0x486a7 in expand_call (exp=(tree) 0x95508, target=(rtx) 0x0, ignore=1, modifier=EXPAND_NORMAL) (expr.c line 4119)
#12 0x46b5c in expand_expr (exp=(tree) 0x95508, target=(rtx) 0x938ac, tmode=VOIDmode, modifier=EXPAND_NORMAL) (expr.c line 2588)
#13 0x4a638 in expand_expr_stmt (exp=(tree) 0x95508) (stmt.c line 1029)
#14 0x2f0af in expand_cplus_expr_stmt (exp=(tree) 0x95508) (cplus-init.c line 3220)
....

Examination of some of the values shows that copy_to_reg is being
passed a (const_int 0) value, and emit_move_insn gets that and (reg
510) (VOIDmode).

I believe I've got all official patches installed, plus obvious
workarounds for other problems (use -d with bison, change "you lose"
to "fatal(...)", &c).  I had no problem building g++, libg++.a, nor
any of the test files that come before tString.cc.

-- Ken

tiemann@SUN.COM (Michael Tiemann) (09/14/89)

If you see this problem:

    A stack trace with gdb:

    (gdb) bt
    #0  0x851ce in abort ()
    #1  0x45436 in emit_move_insn (x=(rtx) 0x1fc0e8, y=(rtx) 0x938ac) (expr.c line 1093)
    #2  0x5077b in copy_to_reg (x=(rtx) 0x938ac) (explow.c line 397)
    #3  0x5062e in memory_address (mode=SImode, x=(rtx) 0x1fc0dc) (explow.c line 303)
    #4  0x5b5cc in copy_rtx_and_substitute (orig=(rtx) 0x19a970) (integrate.c line 1351)
    #5  0x5b8b1 in copy_rtx_and_substitute (orig=(rtx) 0x19a95c) (integrate.c line 1475)
    #6  0x5af9c in expand_inline_function (fndecl=(tree) 0x13e84c, parms=(tree) 0x1fa408, target=(rtx) 0x1fbd20, ignore=0, type=(tree) 0x125480, structure_value_addr=(rtx) 0x1fbd14) (integrate.c line 1013)
    #7  0x486a7 in expand_call (exp=(tree) 0x95528, target=(rtx) 0x1fbd20, ignore=0, modifier=EXPAND_NORMAL) (expr.c line 4119)
    #8  0x478da in expand_expr (exp=(tree) 0x954b8, target=(rtx) 0x0, tmode=VOIDmode, modifier=EXPAND_CONST_ADDRESS) (expr.c line 3190)
    #9  0x47ad3 in expand_expr (exp=(tree) 0x954d8, target=(rtx) 0x0, tmode=SImode,modifier=EXPAND_NORMAL) (expr.c line 3302)
    #10 0x5aaf3 in expand_inline_function (fndecl=(tree) 0x133b54, parms=(tree) 0x1fa4c8, target=(rtx) 0x0, ignore=1, type=(tree) 0x99ea8, structure_value_addr=(rtx) 0x0) (integrate.c line 716)
    #11 0x486a7 in expand_call (exp=(tree) 0x95508, target=(rtx) 0x0, ignore=1, modifier=EXPAND_NORMAL) (expr.c line 4119)
    #12 0x46b5c in expand_expr (exp=(tree) 0x95508, target=(rtx) 0x938ac, tmode=VOIDmode, modifier=EXPAND_NORMAL) (expr.c line 2588)
    #13 0x4a638 in expand_expr_stmt (exp=(tree) 0x95508) (stmt.c line 1029)
    #14 0x2f0af in expand_cplus_expr_stmt (exp=(tree) 0x95508) (cplus-init.c line 3220)
    ....

    Examination of some of the values shows that copy_to_reg is being
    passed a (const_int 0) value, and emit_move_insn gets that and (reg
    510) (VOIDmode).

then this is the solution (replace similar-looking code in
expand_inline_function with this code):

  /* Say where this function starts.  */
  emit_note (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_LINE (fndecl));

  for (formal = DECL_ARGUMENTS (fndecl),
       actual = parms,
       i = 0;
       formal;
       formal = TREE_CHAIN (formal),
       actual = TREE_CHAIN (actual),
       i++)
    {
      /* Actual parameter, already converted to DECL_ARG_TYPE (formal).  */
      tree arg = TREE_VALUE (actual);
      /* Mode of the value supplied.  */
      enum machine_mode tmode = TYPE_MODE (DECL_ARG_TYPE (formal));
      /* Mode of the variable used within the function.  */
      enum machine_mode imode = TYPE_MODE (TREE_TYPE (formal));
      rtx copy;

#if 0
      /* PARM_DECL nodes no longer have this.  */
      emit_note (DECL_SOURCE_FILE (formal), DECL_SOURCE_LINE (formal));
#endif

      /* Make a place to hold the argument value, still in mode TMODE,
	 and put it in COPY.  */
      if (TREE_ADDRESSABLE (formal))
	{
	  int size = int_size_in_bytes (DECL_ARG_TYPE (formal));
	  copy = assign_stack_local (tmode, size);
	  if (!memory_address_p (DECL_MODE (formal), XEXP (copy, 0)))
	    copy = change_address (copy, VOIDmode, copy_rtx (XEXP (copy, 0)));
	  store_expr (arg, copy, 0);
	}
      else if (! TREE_READONLY (formal)
	       || TREE_VOLATILE (formal))
	{
	  /* If parm is modified or if it hasn't a pseudo reg,
	     we may not simply substitute the actual value;
	     copy it through a register.  */
	  copy = gen_reg_rtx (tmode);
	  store_expr (arg, copy, 0);
	}
      else
	{
	  copy = expand_expr (arg, 0, tmode, 0);

	  /* We do not use CONSTANT_ADDRESS_P here because
	     the set of cases where that might make a difference
	     are a subset of the cases that arise even when
	     it is a CONSTANT_ADDRESS_P (i.e., fp_delta
	     gets into the act.

	     If we are not optimizing, then we cannot
	     let constants appear where registers used to,
	     since many machine descriptions won't handle that
	     case.  (The Sparc md, for example.)  */
	  if (GET_CODE (copy) != REG)
	    {
	      if (! CONSTANT_P (copy))
		copy = copy_to_reg (copy);
	      else if (! optimize)
		copy = copy_to_mode_reg (imode, copy);
	    }
	}
      /* If passed mode != nominal mode, COPY is now the passed mode.
	 Convert it to the nominal mode (i.e. truncate it).  */
      if (tmode != imode)
	copy = convert_to_mode (imode, copy, 0);
      arg_vec[i] = copy;
    }

Michael