[Bug c/105868] New: false positive return-local-addr with goto statement and optimization O2

dixyes at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Jun 7 05:42:37 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105868

            Bug ID: 105868
           Summary: false positive return-local-addr with goto statement
                    and optimization O2
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dixyes at gmail dot com
  Target Milestone: ---

Created attachment 53095
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53095&action=edit
retlocal.tar.zst

GCC version/System type:

```
gcc -v

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-bootstrap
--prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-linker-build-id --enable-lto
--enable-multilib --enable-plugin --enable-shared --enable-threads=posix
--disable-libssp --disable-libstdcxx-pch --disable-werror
--with-build-config=bootstrap-lto --enable-link-serialization=1
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.0 (GCC)

uname -a

Linux DIXXPSArch 5.18.1-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 30 May 2022
17:53:11 +0000 x86_64 GNU/Linux
```

This gcc is from archlinux package gcc 12.1.0-2

This also happens at these gccs:

- "12.1.0-2" in debian sid x86_64
- "12.1.1-1.fc37" in fedora rawhide x86_64
- "12.1.1-1.fc36" in fedora 36 x86_64
- "gcc12-12.1.0+git27-1.3" in opensuse tumbleweed x86_64
- "12.1.0-2" in debian sid arm64
- "12.1.0-2.1" in archlinuxarm arm64

This do not happen at these gccs:

- gcc 11
- "12.1.0-2" in debian(ports) sid mips64el
- "12.1.0-2" in debian(ports) sid riscv64

Code:

```
#define NULL ((void *)0)
// gcc -Wextra retlocal.c -c -O2 -o retlocal.o

int uv_os_getenv(const char*, char*, unsigned long long *);
char *func(const char *name, char *buffer, unsigned long long *size)
{
    char _buffer[512] = {0};
    unsigned long long *size_ptr, alloc_size = 0;
    int error;

    if (buffer == NULL) {
        if (size == NULL || *size == 0) {
            alloc_size = sizeof(_buffer);
            size_ptr = &alloc_size;
        } else {
            alloc_size = *size;
            size_ptr = size;
        }
        if (alloc_size <= sizeof(_buffer)) {
            buffer = _buffer;
        } else {
            _retry:
            // using malloc is the same
            buffer = (char *) __builtin_malloc(alloc_size);
        }
    } else {
        size_ptr = size;
    }

    error = uv_os_getenv(name, buffer, size_ptr);

    if (error != 0) {
        if (alloc_size != 0 && buffer != _buffer) {
            // using free is the same
            __builtin_free(buffer);
        }
        if (error == 22 && size_ptr == &alloc_size) {
            // comment out below, things is ok
            goto _retry;
        }
        return NULL;
    }

    if (buffer == _buffer) {
        // using strdup is the same
        buffer = __builtin_strdup(buffer);
    }

    return buffer;
}
```

GCC command:

`gcc -Wextra retlocal.c -c -O2 -o retlocal.o`

Which `-Wextra` includes `-Wreturn-local-addr`, `-O2` is necessary, not sure
which optimization in O2 make this broken.

Outputs:
```
retlocal.c: In function ‘func’:
retlocal.c:51:1: warning: function may return address of local variable
[-Wreturn-local-addr]
   51 | }
      | ^
retlocal.c:8:10: note: declared here
    8 |     char _buffer[512] = {0};
      |          ^~~~~~~         ^~~~~~~
```

Problem:

As you can see if this code wants to return anything other than NULL, it must
reach the end of this function, while before that, a `buffer == _buffer` check
is made, so this piece of code cannot return local address of `_buffer`. The
warning is a false positive, I am not sure if the code it generated is ok.

Tempfiles is in the attachment


More information about the Gcc-bugs mailing list