Bug 91691

Summary: Cross compiling glibc produces a false maybe-uninitialized error
Product: gcc Reporter: Alistair <alistair>
Component: middle-endAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: fw, wilson
Priority: P3 Keywords: diagnostic
Version: 8.3.0   
Target Milestone: ---   
Host: Target: riscv32
Build: x86_64 Known to work:
Known to fail: Last reconfirmed: 2019-10-10 00:00:00
Bug Depends on:    
Bug Blocks: 24639    
Attachments: Output of -save-temps

Description Alistair 2019-09-06 17:30:48 UTC
Created attachment 46845 [details]
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
Comment 1 Alistair 2019-09-06 17:33:44 UTC
The full command line is:

gcc clnt_udp.c -c -std=gnu11 -fgnu89-inline  -O2 -Wall -Wwrite-strings -Wundef -Werror -fmerge-all-constants -frounding-math -fno-stack-protector -Wstrict-prototypes -Wold-style-definition -fmath-errno   -fPIC   -ftls-model=initial-exec      -I../include -I/scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build/sunrpc  -I/scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build  -I../sysdeps/unix/sysv/linux/riscv/rv32  -I../sysdeps/unix/sysv/linux/riscv  -I../sysdeps/riscv/nptl  -I../sysdeps/unix/sysv/linux/generic/wordsize-32  -I../sysdeps/unix/sysv/linux/generic  -I../sysdeps/unix/sysv/linux/include -I../sysdeps/unix/sysv/linux  -I../sysdeps/nptl  -I../sysdeps/pthread  -I../sysdeps/gnu  -I../sysdeps/unix/inet  -I../sysdeps/unix/sysv  -I../sysdeps/unix  -I../sysdeps/posix  -I../sysdeps/riscv/rv32/rvd  -I../sysdeps/riscv/rv32/rvf  -I../sysdeps/riscv/rvf  -I../sysdeps/riscv/rvd  -I../sysdeps/riscv/rv32  -I../sysdeps/riscv  -I../sysdeps/init_array  -I../sysdeps/ieee754/ldbl-128  -I../sysdeps/ieee754/dbl-64  -I../sysdeps/ieee754/flt-32  -I../sysdeps/wordsize-32  -I../sysdeps/ieee754  -I../sysdeps/generic  -I.. -I../libio -I. -nostdinc -isystem /scratch/alistair/software/tier3/buildroot/output/host/lib/gcc/riscv32-buildroot-linux-gnu/8.3.0/include -isystem /scratch/alistair/software/tier3/buildroot/output/host/lib/gcc/riscv32-buildroot-linux-gnu/8.3.0/include-fixed -isystem /scratch/alistair/software/tier3/buildroot/output/host/riscv32-buildroot-linux-gnu/sysroot/usr/include  -D_LIBC_REENTRANT -include /scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build/libc-modules.h -DMODULE_NAME=libc -include ../include/libc-symbols.h  -DPIC -DSHARED     -DTOP_NAMESPACE=glibc -o /scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build/sunrpc/compat-clnt_udp.os -MD -MP -MF /scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build/sunrpc/compat-clnt_udp.os.dt -MT /scratch/alistair/software/tier3/buildroot/output/build/glibc-custom/build/sunrpc/compat-clnt_udp.os -DEXPORT_RPC_SYMBOLS
Comment 2 Alistair 2019-09-06 17:40:26 UTC
I can also reproduce this with the 9.2 release.
Comment 3 Jim Wilson 2019-10-10 01:11:33 UTC
I can reproduce using gcc-8 and gcc-9 but not mainline.  I'm using gcc options:
-std=gnu11 -fgnu89-inline  -mcmodel=medlow -g -O2 -Wall -Wwrite-strings -Wundef 
-fmerge-all-constants -frounding-math -fno-stack-protector -Wstrict-prototypes -
Wold-style-definition -fmath-errno   -fPIC   -ftls-model=initial-exec \
tmp.i -fdump-tree-all -fdump-ipa-all 

Bisecting on mainline shows that the new IPA SRA pass added Sept 20 fixed this.
Without that patch, I see that total_deadline is being decomposed, but apparently there is something wrong with the tracking info. If I add -fno-ipa-sra the warning goes away.

The new IPA-SRA is too big of a patch to backport, so it looks like this will have to remain unfixed on the gcc-8 and gcc-9 branches.
Comment 4 Alistair 2019-10-10 19:06:35 UTC
Thanks for looking into this Jim. We have worked around it in glibc master, so that's fine that it can't be back ported. I'm glad it has been fixed in the latest version.
Comment 5 Jim Wilson 2019-10-11 01:13:35 UTC
Fixed on mainline.  Not backporting to gcc-8 or gcc-9 branches.