The following test case is a mechanical reduction from the implementation of vfprintf in GNU libc: extern void *memset(void *, int, __SIZE_TYPE__); void f(int *a, __builtin_va_list b) { memset(a, 2, sizeof(int)); for (;;) __builtin_va_arg(b, long double); } I get a spurious uninitialized value warning on the __builtin_va_arg line with a powerpc-spe compiler, but not with the exact same build targeting a different architecture -- not even a different powerpc variant: $ powerpc-glibc-linux-gnuspe-gcc -S -O -Wall -Werror vfp_min3.c; echo $? vfp_min3.c: In function ‘f’: vfp_min3.c:6:25: error: ‘va_arg_tmp.3’ is used uninitialized in this function [-Werror=uninitialized] __builtin_va_arg(b, long double); ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~ cc1: all warnings being treated as errors 1 $ powerpc-glibc-linux-gnu-gcc -S -O -Wall -Werror vfp_min3.c; echo $? 0 $ powerpc-glibc-linux-gnuspe-gcc --version powerpc-glibc-linux-gnuspe-gcc (GCC) 7.3.1 20180307 [gcc-7-branch revision 258338] Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ powerpc-glibc-linux-gnu-gcc --version powerpc-glibc-linux-gnu-gcc (GCC) 7.3.1 20180307 [gcc-7-branch revision 258338] Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This is an extra frustrating spurious-uninitialized bug because it's complaining about a variable that doesn't even exist in the source code -- I guess it's a temporary used inside the expansion of __builtin_va_arg? So it might not even be *spurious*, I suppose, it might be telling me that that expansion is wrong!
Can't reproduce. $ ./xgcc -B ./ -v Reading specs from ./specs COLLECT_GCC=./xgcc COLLECT_LTO_WRAPPER=./lto-wrapper Target: powerpc-e500v2-linux-gnuspe Configured with: ../configure --target powerpc-e500v2-linux-gnuspe --disable-bootstrap --enable-languages=c,c++,fortran : (reconfigured) Thread model: posix gcc version 8.0.1 20180309 (experimental) (GCC) $ ./cc1 -quiet -m32 -O2 -Wall -W pr84772.c -nostdinc -mcpu=8540 $ ./cc1 -quiet -m32 -O2 -Wall -W pr84772.c -nostdinc -mcpu=8548 No warnings at all in either. Nor in 7.3.1: $ ./xgcc -B ./ -v Reading specs from ./specs COLLECT_GCC=./xgcc COLLECT_LTO_WRAPPER=./lto-wrapper Target: powerpc-glibc-linux-gnuspe Configured with: ../configure --target powerpc-glibc-linux-gnuspe --disable-bootstrap --enable-languages=c,c++,fortran Thread model: posix gcc version 7.3.1 20180309 (GCC) $ ./cc1 -quiet -O -Wall -W pr84772.c -nostdinc
You don't appear to have the exact same build as me. But there's something fishy going on with that, because as far as I can tell, SVN rev 258338 is a *trunk* revision, not a gcc-7-branch revision. Anyway, I'm gonna attach a .stdarg dump from the compiler that does trigger the problem, maybe comparing that to the .stdarg dump you get will help?
Created attachment 43607 [details] -fdump-tree-stdarg output for test case from problem compiler I do not entirely understand how to read this (what do the _123(D) suffixes on everything mean?) but right after <L3> there sure does appear to be a read of the variable va_arg_tmp.3, which was introduced by this pass, and which does not appear to have been previously initialized.
The last actual _change_ in my GCC build is r258315 | denisc | 2018-03-07 04:13:12 -0500 (Wed, 07 Mar 2018) | 9 lines Backport from mainline 2018-02-07 Georg-Johann Lay <avr@gjlay.de> PR target/84209 * config/avr/avr.h (GENERAL_REGNO_P, GENERAL_REG_P): New macros. * config/avr/avr.md: Only post-reload split REG-REG moves if either register is GENERAL_REG_P.
Ah, I can actually reproduce it with additional -mlong-double-128, both in 7.3 and on the trunk.
Created attachment 43608 [details] gcc8-pr84772.patch Untested fix.
I no longer remember enough about GIMPLE to comment on your actual proposed fix, but I do have a small nitpick on the test case: + va_arg (ap, long double); /* { dg-bogus "may be used uninitialized in this function" } */ I think that needs to be just { dg-bogus "used uninitialized" }, as you might get either the "may be used initialized" or the "is used uninitialized" message.
Author: jakub Date: Fri Mar 9 22:23:14 2018 New Revision: 258399 URL: https://gcc.gnu.org/viewcvs?rev=258399&root=gcc&view=rev Log: PR target/84772 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Mark va_arg_tmp temporary TREE_ADDRESSABLE before gimplification of BUILT_IN_MEMCPY. * config/powerpcspe/powerpcspe.c (rs6000_gimplify_va_arg): Likewise. * gcc.dg/pr84772.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr84772.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/powerpcspe/powerpcspe.c trunk/gcc/config/rs6000/rs6000.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk so far.
Author: jakub Date: Fri Jun 22 20:35:29 2018 New Revision: 261918 URL: https://gcc.gnu.org/viewcvs?rev=261918&root=gcc&view=rev Log: Backported from mainline 2018-03-09 Jakub Jelinek <jakub@redhat.com> PR target/84772 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Mark va_arg_tmp temporary TREE_ADDRESSABLE before gimplification of BUILT_IN_MEMCPY. * gcc.dg/pr84772.c: New test. Added: branches/gcc-7-branch/gcc/testsuite/gcc.dg/pr84772.c Modified: branches/gcc-7-branch/gcc/ChangeLog branches/gcc-7-branch/gcc/config/rs6000/rs6000.c branches/gcc-7-branch/gcc/testsuite/ChangeLog
Author: jakub Date: Mon Jun 25 17:31:23 2018 New Revision: 262074 URL: https://gcc.gnu.org/viewcvs?rev=262074&root=gcc&view=rev Log: Backported from mainline 2018-03-09 Jakub Jelinek <jakub@redhat.com> PR target/84772 * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Mark va_arg_tmp temporary TREE_ADDRESSABLE before gimplification of BUILT_IN_MEMCPY. * gcc.dg/pr84772.c: New test. Added: branches/gcc-6-branch/gcc/testsuite/gcc.dg/pr84772.c Modified: branches/gcc-6-branch/gcc/ChangeLog branches/gcc-6-branch/gcc/config/rs6000/rs6000.c branches/gcc-6-branch/gcc/testsuite/ChangeLog
Fixed for 6.5 and 7.4+ too.