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

            Bug ID: 127898
           Summary: Incorrect -Wsequence-point warning when incrementing
                    an index used by the counted_by attribute after
                    reallocation
           Product: gcc
           Version: 16.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: collin.funk1 at gmail dot com
  Target Milestone: ---

Created attachment 65846
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65846&action=edit
preprocessed file

I've been gradually adding use of the counted_by attribute to GNU coreutils.
Yesterday, I noticed a -Wsequence-point warning that I suspect is incorrect
[1]. Here is a simplified reproducer:

```
$ cat main.c
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
static struct
{
  ptrdiff_t len;
  ptrdiff_t size;
  char *data __attribute__ ((__counted_by__ (len)));
} buffer;

static void
append_1 (char c)
{
  if (buffer.size <= buffer.len)
    buffer.data = realloc (buffer.data, ++buffer.size);
  buffer.data[buffer.len++] = c;
}

int
main (void)
{
  const char str[] = "Hello, world!\n";
  for (char const *p = str; *p; ++p)
    append_1 (*p);
  return ((fwrite (buffer.data, sizeof *buffer.data, buffer.len, stdout)
           == buffer.len)
          ? EXIT_SUCCESS : EXIT_FAILURE);
}
```

Here is the warning seen when compiling:

```
$ gcc -Wsequence-point main.c
main.c: In function 'append_1':
main.c:16:25: warning: operation on 'buffer.len' may be undefined
[-Wsequence-point]
   16 |   buffer.data[buffer.len++] = c;
      |               ~~~~~~~~~~^~
```

Initially, I noticed this using the GCC 16.2.1 binary distributed with Fedora
44. But I can also confirm it occurs with GCC built from trunk, commit
84348add236100e5f69a3e9ec4f7b1038bf2b83d at the time of writing.

My memory of the sequence point rules is poor, but I don't see any issues with
that code. The memory at `buffer.data` is read using the current value of
`buffer.len` as the index, and then `buffer.len` is incremented. FWIW,
`-fsanitize=bounds` is satisfied by this code and `clang -Wsequence-point` is
not triggered, at least using the 22.1.8 build distributed by Fedora.

Here is the full compiler command-line and its output, used to generate the
preprocessed source:

```
$ gcc -v -save-temps -Wsequence-point main.c 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/collin/.local/src/gcc/configure
--prefix=/home/collin/tmp --enable-languages=c,c++ --disable-multiarch
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 17.0.0 20261015 (experimental) (GCC) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wsequence-point' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 /home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/cc1 -E -quiet -v
main.c -mtune=generic -march=x86-64 -Wsequence-point -fpch-preprocess -o
a-main.i
ignoring nonexistent directory
"/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/include
 /usr/local/include
 /home/collin/tmp/include
 /home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/include-fixed
 /usr/include
End of search list.
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wsequence-point' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 /home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/cc1 -fpreprocessed
a-main.i -quiet -dumpdir a- -dumpbase main.c -dumpbase-ext .c -mtune=generic
-march=x86-64 -Wsequence-point -version -o a-main.s
GNU C23 (GCC) version 17.0.0 20261015 (experimental) (x86_64-pc-linux-gnu)
        compiled by GNU C version 17.0.0 20261015 (experimental), GMP version
6.3.0, MPFR version 4.2.2, MPC version 1.4.1, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: d088e783fe285b2c8d9cdf89659291b4
main.c: In function ‘append_1’:
main.c:16:25: warning: operation on ‘buffer.len’ may be undefined
[-Wsequence-point]
   16 |   buffer.data[buffer.len++] = c;
      |               ~~~~~~~~~~^~
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wsequence-point' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 as -v --64 -o a-main.o a-main.s
GNU assembler version 2.46.1 (x86_64-redhat-linux) using BFD version version
2.46.1-1.fc44
COMPILER_PATH=/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/:/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/:/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/:/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/:/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/:/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wsequence-point' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a.'
 /home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/collect2 -plugin
/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/liblto_plugin.so
-plugin-opt=/home/collin/tmp/libexec/gcc/x86_64-pc-linux-gnu/17.0.0/lto-wrapper
-plugin-opt=-fresolution=a.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s_asneeded
-plugin-opt=-pass-through=-latomic_asneeded -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s_asneeded
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2
/lib/../lib64/crt1.o /lib/../lib64/crti.o
/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/crtbegin.o
-L/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0
-L/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/../../../../lib64
-L/lib/../lib64 -L/usr/lib/../lib64
-L/home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/../../.. -L/lib
-L/usr/lib a-main.o -lgcc -lgcc_s_asneeded -latomic_asneeded -lc -lgcc
-lgcc_s_asneeded /home/collin/tmp/lib/gcc/x86_64-pc-linux-gnu/17.0.0/crtend.o
/lib/../lib64/crtn.o
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wsequence-point' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a.'
```

[1] https://lists.gnu.org/archive/html/coreutils/2026-10/msg00072.html

Reply via email to