Bug 95818 - wrong "used uninitialized" warning
Summary: wrong "used uninitialized" warning
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wuninitialized
  Show dependency treegraph
 
Reported: 2020-06-22 12:53 UTC by Ferruh YIGIT
Modified: 2020-06-23 01:58 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-06-22 00:00:00


Attachments
preprocessed source (155.29 KB, application/x-xz)
2020-06-22 23:55 UTC, Ferruh YIGIT
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ferruh YIGIT 2020-06-22 12:53:46 UTC
gcc (GCC) 11.0.0 20200621 (experimental)

Sorry, I couldn't able to reproduce with test code, I will copy-paste the real code that causes the warning hoping it helps.

Warning [1] and code that causes it [2], struct in question [3].

As you can see all the fields of the struct has been set before used, so not sure why giving used uninitialized warning.



[1]
.../drivers/net/iavf/iavf_ethdev.c: In function ‘iavf_dev_link_update’:
.../drivers/net/iavf/iavf_ethdev.c:641:6: error: ‘new_link’ is used uninitialized [-Werror=uninitialized]
  641 |  if (rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  642 |     *(uint64_t *)&dev->data->dev_link,
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  643 |     *(uint64_t *)&new_link) == 0)
      |     ~~~~~~~~~~~~~~~~~~~~~~~
.../drivers/net/iavf/iavf_ethdev.c:596:22: note: ‘new_link’ declared here
  596 |  struct rte_eth_link new_link;
      |                      ^~~~~~~~
cc1: all warnings being treated as error



[2]
iavf_dev_link_update(struct rte_eth_dev *dev,
                    __rte_unused int wait_to_complete)
{
        struct rte_eth_link new_link;
        struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);

        /* Only read status info stored in VF, and the info is updated
         *  when receive LINK_CHANGE evnet from PF by Virtchnnl.
         */
        switch (vf->link_speed) {
        case 10:
                new_link.link_speed = ETH_SPEED_NUM_10M;
                break;
        case 100:
                new_link.link_speed = ETH_SPEED_NUM_100M;
                break;
        case 1000:
                new_link.link_speed = ETH_SPEED_NUM_1G;
                break;
        case 10000:
                new_link.link_speed = ETH_SPEED_NUM_10G;
                break;
        case 20000:
                new_link.link_speed = ETH_SPEED_NUM_20G;
                break;
        case 25000:
                new_link.link_speed = ETH_SPEED_NUM_25G;
                break;
        case 40000:
                new_link.link_speed = ETH_SPEED_NUM_40G;
                break;
        case 50000:
                new_link.link_speed = ETH_SPEED_NUM_50G;
                break;
        case 100000:
                new_link.link_speed = ETH_SPEED_NUM_100G;
                break;
        default:
                new_link.link_speed = ETH_SPEED_NUM_NONE;
                break;
        }

        new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
        new_link.link_status = vf->link_up ? ETH_LINK_UP :
                                             ETH_LINK_DOWN;
        new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
                                ETH_LINK_SPEED_FIXED);

        if (rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
                                *(uint64_t *)&dev->data->dev_link,
                                *(uint64_t *)&new_link) == 0)
                return -1;

        return 0;
}



[3]
struct rte_eth_link {
        uint32_t link_speed;        /**< ETH_SPEED_NUM_ */
        uint16_t link_duplex  : 1;  /**< ETH_LINK_[HALF/FULL]_DUPLEX */
        uint16_t link_autoneg : 1;  /**< ETH_LINK_[AUTONEG/FIXED] */
        uint16_t link_status  : 1;  /**< ETH_LINK_[DOWN/UP] */
} __rte_aligned(8);      /**< aligned for atomic64 read/write */
Comment 1 Richard Biener 2020-06-22 13:00:22 UTC
please provide complete preprocessed source
Comment 2 Ferruh YIGIT 2020-06-22 15:11:59 UTC
.i output [1] and .s output [2] below, please let me know if the request was something else.

[1]
int
iavf_dev_link_update(struct rte_eth_dev *dev,
      __attribute__((__unused__)) int wait_to_complete)
{
 struct rte_eth_link new_link;
 struct iavf_info *vf = (&((struct iavf_adapter *)dev->data->dev_private)->vf);




 switch (vf->link_speed) {
 case 10:
  new_link.link_speed = 10;
  break;
 case 100:
  new_link.link_speed = 100;
  break;
 case 1000:
  new_link.link_speed = 1000;
  break;
 case 10000:
  new_link.link_speed = 10000;
  break;
 case 20000:
  new_link.link_speed = 20000;
  break;
 case 25000:
  new_link.link_speed = 25000;
  break;
 case 40000:
  new_link.link_speed = 40000;
  break;
 case 50000:
  new_link.link_speed = 50000;
  break;
 case 100000:
  new_link.link_speed = 100000;
  break;
 default:
  new_link.link_speed = 0;
  break;
 }

 new_link.link_duplex = 1;
 new_link.link_status = vf->link_up ? 1 :
          0;
 new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
    (1 << 0));

 if (rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
    *(uint64_t *)&dev->data->dev_link,
    *(uint64_t *)&new_link) == 0)
  return -1;

 return 0;
}



[2]
        .globl  iavf_dev_link_update
        .type   iavf_dev_link_update, @function iavf_dev_link_update:
.LFB6034:
        .cfi_startproc
        movq    24(%rdi), %rcx
        movq    96(%rcx), %rsi
        movl    476(%rsi), %edx
        cmpl    $20000, %edx
        je      .L5
        jbe     .L28
        cmpl    $50000, %edx
        je      .L5
        jbe     .L29
        cmpl    $100000, %edx
        movl    $0, %eax
        cmovne  %rax, %rdx
.L5:
        movl    112(%rcx), %eax
        movzbl  473(%rsi), %esi
        notl    %eax
        andl    $1, %eax
        sall    $2, %esi
        leal    1(%rax,%rax), %eax
        orl     %esi, %eax
        andl    $7, %eax
        salq    $32, %rax
        orq     %rax, %rdx
        movq    104(%rcx), %rax
#APP
# 33 "/root/development/dpdk-next-net/build/include/rte_atomic_64.h" 1
        lock ; cmpxchgq %rdx, 104(%rcx);sete %al;
# 0 "" 2
#NO_APP
        cmpb    $1, %al
        sbbl    %eax, %eax
        ret
        .p2align 4,,10
        .p2align 3
.L29:
        cmpl    $25000, %edx
        je      .L5
        cmpl    $40000, %edx
        je      .L5
.L11:
        xorl    %edx, %edx
        jmp     .L5
        .p2align 4,,10
        .p2align 3
.L28:
        cmpl    $1000, %edx
        je      .L5
        jbe     .L30
        cmpl    $10000, %edx
        movl    $0, %eax
        cmovne  %rax, %rdx
        jmp     .L5
        .p2align 4,,10
        .p2align 3
.L30:
        cmpl    $10, %edx
        je      .L5
        cmpl    $100, %edx
        je      .L5
        jmp     .L11
        .cfi_endproc
.LFE6034:
        .size   iavf_dev_link_update, .-iavf_dev_link_update
        .p2align 4
Comment 3 Marc Glisse 2020-06-22 19:29:06 UTC
Richard said "complete", that is the whole .i file, not just one random function. If we cannot reproduce the issue by copying your code and compiling it, we can't do anything about your report.
Comment 4 Ferruh YIGIT 2020-06-22 23:55:32 UTC
Created attachment 48772 [details]
preprocessed source
Comment 5 Ferruh YIGIT 2020-06-22 23:59:15 UTC
Got it, 'iavf_ethdev.i' attached.

I am able to reproduce with command [1] and got the output [2] using .i file.

[1]
/usr/local/gcc-latest/bin/gcc -m64 -pthread -march=native -O3 -Wall -Werror -Wno-strict-aliasing -v -save-temps -o iavf_ethdev.o -x cpp-output iavf_ethdev.i


[2]
Using built-in specs.
COLLECT_GCC=/usr/local/gcc-latest/bin/gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-latest/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-latest/configure --prefix=/usr/local/gcc-latest : (reconfigured) ../gcc-latest/configure --prefix=/usr/local/gcc-latest --enable-languages=c,c++,fortran,lto,objc --no-create --no-recursion
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.0.0 20200621 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-m64' '-pthread' '-march=native' '-O3' '-Wall' '-Werror' '-Wno-strict-aliasing' '-v' '-save-temps' '-o' 'iavf_ethdev.o' '-dumpdir' 'iavf_ethdev.o-'
 /usr/local/gcc-latest/libexec/gcc/x86_64-pc-linux-gnu/11.0.0/cc1 -fpreprocessed iavf_ethdev.i -march=skylake-avx512 -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mmovbe -maes -mno-sha -mpclmul -mpopcnt -mabm -mno-lwp -mfma -mno-fma4 -mno-xop -mbmi -mno-sgx -mbmi2 -mno-pconfig -mno-wbnoinvd -mno-tbm -mavx -mavx2 -msse4.2 -msse4.1 -mlzcnt -mrtm -mhle -mrdrnd -mf16c -mfsgsbase -mrdseed -mprfchw -madx -mfxsr -mxsave -mxsaveopt -mavx512f -mno-avx512er -mavx512cd -mno-avx512pf -mno-prefetchwt1 -mclflushopt -mxsavec -mxsaves -mavx512dq -mavx512bw -mavx512vl -mno-avx512ifma -mno-avx512vbmi -mno-avx5124fmaps -mno-avx5124vnniw -mclwb -mno-mwaitx -mno-clzero -mpku -mno-rdpid -mno-gfni -mno-shstk -mno-avx512vbmi2 -mno-avx512vnni -mno-vaes -mno-vpclmulqdq -mno-avx512bitalg -mno-avx512vpopcntdq -mno-movdiri -mno-movdir64b -mno-waitpkg -mno-cldemote -mno-ptwrite -mno-avx512bf16 -mno-enqcmd -mno-avx512vp2intersect -mno-serialize -mno-tsxldtrk --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=33792 -mtune=skylake-avx512 -quiet -dumpdir iavf_ethdev.o- -dumpbase iavf_ethdev.i -dumpbase-ext .i -m64 -O3 -Wall -Werror -Wno-strict-aliasing -version -o iavf_ethdev.o-iavf_ethdev.s
GNU C17 (GCC) version 11.0.0 20200621 (experimental) (x86_64-pc-linux-gnu)
        compiled by GNU C version 11.0.0 20200621 (experimental), GMP version 6.1.2, MPFR version 3.1.6-p2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
GNU C17 (GCC) version 11.0.0 20200621 (experimental) (x86_64-pc-linux-gnu)
        compiled by GNU C version 11.0.0 20200621 (experimental), GMP version 6.1.2, MPFR version 3.1.6-p2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 6a7f176d54144e44e3ed475e12ec1e06
.../net/iavf/iavf_ethdev.c: In function ‘iavf_dev_link_update’:
.../net/iavf/iavf_ethdev.c:641:6: error: ‘new_link’ is used uninitialized [-Werror=uninitialized]
  641 |  if (rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  642 |     *(uint64_t *)&dev->data->dev_link,
      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  643 |     *(uint64_t *)&new_link) == 0)
      |     ~~~~~~~~~~~~~~~~~~~~~~~
.../net/iavf/iavf_ethdev.c:596:22: note: ‘new_link’ declared here
  596 |  struct rte_eth_link new_link;
      |                      ^~~~~~~~
cc1: all warnings being treated as errors
Comment 6 Martin Sebor 2020-06-23 00:21:45 UTC
This instance of the warning looks familiar but I can't reproduce it with my build of the kernel.  The code in the test case isn't valid (it triggers both -Wstrict-aliasing and -Wuninitialized), and I don't think it's safe either.  Only the leading 48 bits of the struct are initialized (by GCC; the program initializes just 35 bits) but the access is to the full 64 bits.  Clearing the whole struct by calling memset avoids the -Wuninitialized.

A small test case that reproduces both warnings is below.

$ cat z.c && gcc -O2 -S -Wall -fdump-tree-uninit=/dev/stdout z.c
struct S
{
  int a;
  short i: 1;
};

void f (long);

void g (void)
{
  struct S s;
  s.a = 0;
  s.i = 1;
  f (*(long*)&s);
}
z.c: In function ‘g’:
z.c:14:7: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
   14 |   f (*(long*)&s);
      |       ^~~~~~~~~
z.c:14:3: warning: ‘s’ is used uninitialized [-Wuninitialized]
   14 |   f (*(long*)&s);
      |   ^~~~~~~~~~~~~~
z.c:11:12: note: ‘s’ declared here
   11 |   struct S s;
      |            ^

;; Function g (g, funcdef_no=0, decl_uid=1937, cgraph_uid=1, symbol_order=0)

g ()
{
  struct S s;
  long int _1;

  <bb 2> [local count: 1073741824]:
  s.a = 0;
  s.i = -1;
  _1 = MEM[(long int *)&s];
  f (_1); [tail call]
  s ={v} {CLOBBER};
  return;

}
Comment 7 Ferruh YIGIT 2020-06-23 00:35:30 UTC
Thanks Martin, explanation and sample clarified the issue for me.
Sorry for the inconvenience caused.
Comment 8 Martin Sebor 2020-06-23 01:58:50 UTC
No problem (and no inconvenience either).