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 <setjmp.h>

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 = &local_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 00    mov    0x0(%rip),%rbx        # 36
<trigger+0x36>
  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          lea    0x20(%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 00    mov    0x0(%rip),%rbx        # 43
<trigger+0x43>
  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.

Reply via email to