[Bug c/91691] New: Cross compiling glibc produces a false maybe-uninitialized error

alistair at alistair23 dot me gcc-bugzilla@gcc.gnu.org
Fri Sep 6 17:30:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91691

            Bug ID: 91691
           Summary: Cross compiling glibc produces a false
                    maybe-uninitialized error
           Product: gcc
           Version: 8.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: alistair at alistair23 dot me
  Target Milestone: ---
            Target: riscv32
             Build: x86_64

Created attachment 46845
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46845&action=edit
Output of -save-temps

When cross compiling the RISC-V 32-bit port/fork of glibc [1] the following
warning/error is seen:

In file included from clnt_udp.c:58:
clnt_udp.c: In function 'clntudp_call':
../inet/net-internal.h:107:13: error: '*((void *)&total_deadline+8)' may be
used uninitialized in this function [-Werror=maybe-uninitialized]
         || (current.current.tv_sec == deadline.absolute.tv_sec
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
             && current.current.tv_nsec >= deadline.absolute.tv_nsec));
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
clnt_udp.c:293:19: note: '*((void *)&total_deadline+8)' was declared here
   struct deadline total_deadline; /* Determined once by overall timeout.  */
                   ^~~~~~~~~~~~~~
In file included from clnt_udp.c:58:
../inet/net-internal.h:116:7: error: 'total_deadline' may be used uninitialized
in this function [-Werror=maybe-uninitialized]
   if (__deadline_is_infinite (right)
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       || left.absolute.tv_sec < right.absolute.tv_sec
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       || (left.absolute.tv_sec == right.absolute.tv_sec
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           && left.absolute.tv_nsec < right.absolute.tv_nsec))
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
clnt_udp.c:293:19: note: 'total_deadline' was declared here
   struct deadline total_deadline; /* Determined once by overall timeout.  */
                   ^~~~~~~~~~~~~~

This occurs in the clntudp_call) function in glibcs sunrpc/clnt_udp.c.

The code looks like this:

...
  struct deadline total_deadline; /* Determined once by overall timeout.  */
  struct deadline response_deadline; /* Determined anew for each query.  */

  /* Choose the timeout value.  For non-sending usage (xargs == NULL),
     the total deadline does not matter, only cu->cu_wait is used
     below.  */
  if (xargs != NULL)
    {
      struct timeval tv;
      if (cu->cu_total.tv_usec == -1)
        /* Use supplied timeout.  */
        tv = utimeout;
      else
        /* Use default timeout.  */
        tv = cu->cu_total;
      if (!__is_timeval_valid_timeout (tv))
        return (cu->cu_error.re_status = RPC_TIMEDOUT);
      total_deadline = __deadline_from_timeval (current_time, tv);
    }

  /* Guard against bad timeout specification.  */
  if (!__is_timeval_valid_timeout (cu->cu_wait))
    return (cu->cu_error.re_status = RPC_TIMEDOUT);

call_again:
  xdrs = &(cu->cu_outxdrs);
  if (xargs == NULL)
    goto get_reply;
  xdrs->x_op = XDR_ENCODE;
  XDR_SETPOS (xdrs, cu->cu_xdrpos);
  /*
   * the transaction is the first thing in the out buffer
   */
  (*(uint32_t *) (cu->cu_outbuf))++;
  if ((!XDR_PUTLONG (xdrs, (long *) &proc)) ||
      (!AUTH_MARSHALL (cl->cl_auth, xdrs)) ||
      (!(*xargs) (xdrs, argsp)))
    return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
  outlen = (int) XDR_GETPOS (xdrs);

send_again:
  if (__sendto (cu->cu_sock, cu->cu_outbuf, outlen, 0,
                (struct sockaddr *) &(cu->cu_raddr), cu->cu_rlen)
      != outlen)
    {
      cu->cu_error.re_errno = errno;
      return (cu->cu_error.re_status = RPC_CANTSEND);
    }

  /* sendto may have blocked, so recompute the current time.  */
  current_time = __deadline_current_time ();
 get_reply:
  response_deadline = __deadline_from_timeval (current_time, cu->cu_wait);

  reply_msg.acpted_rply.ar_verf = _null_auth;
  reply_msg.acpted_rply.ar_results.where = resultsp;
  reply_msg.acpted_rply.ar_results.proc = xresults;
  fd.fd = cu->cu_sock;
  fd.events = POLLIN;
  anyup = 0;

  /* Per-response retry loop.  current_time must be up-to-date at the
     top of the loop.  */
  for (;;)
    {
      int milliseconds;
      if (xargs != NULL)
        {
          if (__deadline_elapsed (current_time, total_deadline))
            /* Overall timeout expired.  */
            return (cu->cu_error.re_status = RPC_TIMEDOUT);
          milliseconds = __deadline_to_ms
            (current_time, __deadline_first (total_deadline,
                                             response_deadline));
          if (milliseconds == 0)
            /* Per-query timeout expired.  */
            goto send_again;
        }
...

So although it is confusing, the total_deadline variable can not be used
uninitalised.

Initalising total_deadline to 0 will fix the warning.

1: https://github.com/alistair23/glibc/tree/gcc-bug


More information about the Gcc-bugs mailing list