[gnu.gcc.bug] Problem Compiling GCC on Sun 4

frank@morgan.com (Frank Wortner) (09/20/88)

I had a problem compiling GCC 1.28 on a Sun 4 (SPARC CPU) running SunOS 4.0.
I was using Sun's C compiler to bootstrap compile GCC.  I followed all
the instructions in the INSTALL file regarding which links to make,
etc.  When I ran the make, here is the result:

cc -g  -sun4 -c  expr.c
"expr.c", line 1420: nonunique name demands struct/union or struct/union pointer
"expr.c", line 1422: nonunique name demands struct/union or struct/union pointer
"expr.c", line 1465: nonunique name demands struct/union or struct/union pointer
"expr.c", line 1468: nonunique name demands struct/union or struct/union pointer
*** Error code 1

All the lines are in the function emit_library call.  I've enclosed a
copy of the function at the end of the message.  I've marked the lines
in question with their line numbers followed by >>>.

This error did not occur when I set up and compiled GCC on a Sun 3
(68020 CPU) under SunOS 4.0.  There the compiler source compiled with
no problems, producing a working GCC which compiled itself correctly.

I hope that this has been helpful.  If not, please tell me if I can do
anything else for you.

						Frank
						frank@morgan.com
						uunet!mstan!frank

---------------------Source Code Follows---------------------------------------
void
emit_library_call (va_alist)
     va_dcl
{
  register va_list p;
  register int args_size = 0;
  register int argnum;
  enum machine_mode outmode;
  int nargs;
  rtx fun;
  rtx orgfun;
  int inc;
  int count;
  rtx *regvec;
  rtx argblock = 0;
  CUMULATIVE_ARGS args_so_far;
  struct arg { rtx value; enum machine_mode mode; };
  struct arg *argvec;
  int old_args_size = current_args_size;

  va_start (p);
  orgfun = fun = va_arg (p, rtx);
  outmode = va_arg (p, enum machine_mode);
  nargs = va_arg (p, int);

  regvec = (rtx *) alloca (nargs * sizeof (rtx));

  /* Copy all the libcall-arguments out of the varargs data
     and into a vector ARGVEC.  */
  argvec = (struct arg *) alloca (nargs * sizeof (struct arg));
  for (count = 0; count < nargs; count++)
    {
      argvec[count].value = va_arg (p, rtx);
      argvec[count].mode = va_arg (p, enum machine_mode);
    }
  va_end (p);

  /* If we have no actual push instructions, make space for all the args
     right now.  */
#ifndef PUSH_ROUNDING
  INIT_CUMULATIVE_ARGS (args_so_far, (tree)0);
  for (count = 0; count < nargs; count++)
    {
      register enum machine_mode mode = argvec[count].mode;
      register rtx reg;
      register int partial;

1420>>>      reg = FUNCTION_ARG (args_so_far, mode, 0, 1);
#ifdef FUNCTION_ARG_PARTIAL_NREGS
1422>>>      partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, 0, 1);
#else
      partial = 0;
#endif
      if (reg == 0 || partial != 0)
	args_size += GET_MODE_SIZE (mode);
      if (partial != 0)
	args_size -= partial * GET_MODE_SIZE (SImode);
      FUNCTION_ARG_ADVANCE (args_so_far, mode, 0, 1);
    }

  if (args_size != 0)
    argblock
      = push_block (round_push (gen_rtx (CONST_INT, VOIDmode, args_size)));
#endif

  INIT_CUMULATIVE_ARGS (args_so_far, (tree)0);

#ifdef PUSH_ARGS_REVERSED
  inc = -1;
  argnum = nargs - 1;
#else
  inc = 1;
  argnum = 0;
#endif
  args_size = 0;

  for (count = 0; count < nargs; count++, argnum += inc)
    {
      register enum machine_mode mode = argvec[argnum].mode;
      register rtx val = argvec[argnum].value;
      rtx reg;
      int partial;
      int arg_size;

      /* Convert the arg value to the mode the library wants.  */
      /* ??? It is wrong to do it here; must do it earlier
	 where we know the signedness of the arg.  */
      if (GET_MODE (val) != mode && GET_MODE (val) != VOIDmode)
	{
	  val = gen_reg_rtx (mode);
	  convert_move (val, argvec[argnum].value, 0);
	}
1465>>>      reg = FUNCTION_ARG (args_so_far, mode, 0, 1);
      regvec[argnum] = reg;
#ifdef FUNCTION_ARG_PARTIAL_NREGS
1468>>>      partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, 0, 1);
#else
      partial = 0;
#endif

      if (reg != 0 && partial == 0)
	emit_move_insn (reg, val);
      else
	emit_push_insn (val, mode, 0, 0, partial, reg, 0, argblock,
			gen_rtx (CONST_INT, VOIDmode, args_size));

      /* Compute size of stack space used by this argument.  */
      if (reg == 0 || partial != 0)
	arg_size = GET_MODE_SIZE (mode);
      else
	arg_size = 0;
      if (partial != 0)
	arg_size
	  -= ((partial * UNITS_PER_WORD)
	      / (PARM_BOUNDARY / BITS_PER_UNIT)
	      * (PARM_BOUNDARY / BITS_PER_UNIT));

      args_size += arg_size;
      NO_DEFER_POP;
      FUNCTION_ARG_ADVANCE (args_so_far, mode, 0, 1);
    }

  emit_queue ();

  fun = prepare_call_address (fun, 0);

  /* Any regs containing parms remain in use through the call.
     ??? This is not quite correct, since it doesn't indicate
     that they are in use immediately before the call insn.
     Currently that doesn't matter since explicitly-used regs
     won't be used for reloading.  But if the reloader becomes smarter,
     this will have to change somehow.  */
  for (count = 0; count < nargs; count++)
    if (regvec[count] != 0)
      emit_insn (gen_rtx (USE, VOIDmode, regvec[count]));

#ifdef STACK_BOUNDARY
  args_size = (args_size + STACK_BYTES - 1) / STACK_BYTES * STACK_BYTES;
#endif

  /* Don't allow popping to be deferred, since then
     cse'ing of library calls could delete a call and leave the pop.  */
  NO_DEFER_POP;
  emit_call_1 (fun, get_identifier (XSTR (orgfun, 0)), args_size,
	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
	       outmode != VOIDmode ? hard_libcall_value (outmode) : 0,
	       old_args_size + 1);
  OK_DEFER_POP;
}