This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, fortran]: prevent clobbered by 'longjmp' or 'vfork


Andrew,
    I thought the problem is that once setjmp() is called, any additional
calls to longjump or vfork would leave type with an indeterminate value.
The code in question has a lot of subroutine calls between the setjmp()
and the later uses of type....

static void
list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
                            size_t size)
{
  char c;
  int m;
  jmp_buf eof_jump;

  dtp->u.p.namelist_mode = 0;

  dtp->u.p.eof_jump = &eof_jump;
  if (setjmp (eof_jump))
    {
      generate_error (&dtp->common, ERROR_END, NULL);
      goto cleanup;
    }

  if (dtp->u.p.first_item)
    {
      dtp->u.p.first_item = 0;
      dtp->u.p.input_complete = 0;
      dtp->u.p.repeat_count = 1;
      dtp->u.p.at_eol = 0;

      c = eat_spaces (dtp);
      if (is_separator (c))
        {                       /* Found a null value.  */
          eat_separator (dtp);
          dtp->u.p.repeat_count = 0;

          /* eat_separator sets this flag if the separator was a comma */
          if (dtp->u.p.comma_flag)
            goto cleanup;

          /* eat_separator sets this flag if the separator was a \n or \r */
          if (dtp->u.p.at_eol)
            finish_separator (dtp);
          else
            goto cleanup;
        }

    }
  else
    {
      if (dtp->u.p.input_complete)
        goto cleanup;

      if (dtp->u.p.repeat_count > 0)
        {
          if (check_type (dtp, type, kind))
            return;
          goto set_value;
        }

      if (dtp->u.p.at_eol)
        finish_separator (dtp);
      else
        {
          eat_spaces (dtp);
          /* trailing spaces prior to end of line */
          if (dtp->u.p.at_eol)
            finish_separator (dtp);
        }

      dtp->u.p.saved_type = BT_NULL;
      dtp->u.p.repeat_count = 1;
    }

  switch (type)
    {
    case BT_INTEGER:
      read_integer (dtp, kind);
      break;
    case BT_LOGICAL:
      read_logical (dtp, kind);
      break;
    case BT_CHARACTER:
      read_character (dtp, kind);
      break;
    case BT_REAL:
      read_real (dtp, kind);
      break;
    case BT_COMPLEX:
      read_complex (dtp, kind, size);
      break;
    default:
      internal_error (&dtp->common, "Bad type for list read");
    }

  if (dtp->u.p.saved_type != BT_CHARACTER && dtp->u.p.saved_type != BT_NULL)
    dtp->u.p.saved_length = size;

  if ((dtp->common.flags & IOPARM_LIBRETURN_MASK) != IOPARM_LIBRETURN_OK)
    goto cleanup;

 set_value:
  switch (dtp->u.p.saved_type)
    {
    case BT_COMPLEX:
    case BT_INTEGER:
    case BT_REAL:
    case BT_LOGICAL:
      memcpy (p, dtp->u.p.value, size);
      break;

    case BT_CHARACTER:
      if (dtp->u.p.saved_string)
       {
          m = ((int) size < dtp->u.p.saved_used)
              ? (int) size : dtp->u.p.saved_used;
          memcpy (p, dtp->u.p.saved_string, m);
       }
      else
        /* Just delimiters encountered, nothing to copy but SPACE.  */
        m = 0;

      if (m < (int) size)
        memset (((char *) p) + m, ' ', size - m);
      break;

    case BT_NULL:
      break;
    }

  if (--dtp->u.p.repeat_count <= 0)
    free_saved (dtp);

cleanup:
  dtp->u.p.eof_jump = NULL;
}

Can you really be sure that neither longjmp or vfork will be invoked
in those subroutine calls?
                      Jack
ps I also found another discussion of this at...

http://mail.python.org/pipermail/python-dev/2000-July/005432.html


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]