https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91395
Bug ID: 91395
Summary: Report an uninitialized variable on its initialization
statement (setjmp)
Product: gcc
Version: 9.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: ali at pivotal dot io
Target Milestone: ---
Version:
$ gcc-9 --version
gcc-9 (Ubuntu 9.1.0-2ubuntu2~19.04) 9.1.0
(Actually from gcc 7)
Reproducer:
```
#include
extern int other(void);
extern void trigger(int *cond1);
extern sigjmp_buf *global_exception_stack;
void
trigger(int *cond1)
{
while (1)
{
if (*cond1 == 0)
*cond1 = other();
while (*cond1)
{
sigjmp_buf *save_exception_stack =
global_exception_stack;
sigjmp_buf local_sigjmp_buf;
if (sigsetjmp(local_sigjmp_buf, 0) == 0)
global_exception_stack = _sigjmp_buf;
else
global_exception_stack = (sigjmp_buf *)
save_exception_stack;
global_exception_stack = (sigjmp_buf *)
save_exception_stack;
}
}
}
```
```
$ gcc-9 -O1 -Werror=uninitialized -fexpensive-optimizations -ftree-pre -c -o
/dev/null reproducer.c
reproducer.c: In function 'trigger':
reproducer.c:17:16: error: 'save_exception_stack' is used uninitialized in this
function [-Werror=uninitialized]
17 |sigjmp_buf *save_exception_stack = global_exception_stack;
|^~~~
cc1: some warnings being treated as errors
```
Observation:
1, asm code re-ordering matters.
2, when it reports warning, initializing asm codes are before the setjmp().
When it warns:
```
sigjmp_buf *save_exception_stack = PG_exception_stack;
2f: 48 8b 1d 00 00 00 00mov0x0(%rip),%rbx# 36
36: 48 89 5c 24 18 mov%rbx,0x18(%rsp)
sigjmp_buf local_sigjmp_buf;
if (sigsetjmp(local_sigjmp_buf, 0) == 0)
```
When it doesn't complain:
```
sigjmp_buf *save_exception_stack = PG_exception_stack;
sigjmp_buf local_sigjmp_buf;
if (sigsetjmp(local_sigjmp_buf, 0) == 0)
29: 48 8d 44 24 20 lea0x20(%rsp),%rax
2e: 48 89 44 24 08 mov%rax,0x8(%rsp)
...
sigjmp_buf *save_exception_stack = PG_exception_stack;
3c: 48 8b 1d 00 00 00 00mov0x0(%rip),%rbx# 43
43: 48 89 5c 24 18 mov%rbx,0x18(%rsp)
```
I guess it might be an optimization regression of gcc, it was always smart
enough to reorder the local variables to avoid this issue (initializing them
after setjmp() obviously has no such issue because it will be initialized as we
wish after longjmp() wherever anyway), but higher version gcc's updates lost
the optimization in some cases.