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

            Bug ID: 119429
           Summary: size_t __nargs = -1 in std::format
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: desmond.rhodes at outlook dot com
  Target Milestone: ---

I'm using `ubuntu:bookworm` with `/etc/apt/sources.list.d/debian.sources`:

```
Types: deb
URIs: http://deb.debian.org/debian
Suites: sid
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
```

I compile with `clang++` version `19.1.7-3`, and `libstdc++` version
`14.2.0-19`.

The bug is triggered when I use `-fsanitize=integer`.

Here's the minimum program to produce the error:

```
/* example.cc */
#include <print>
int main() {
        std::print("Hello, world!\n");
        return 0;
}
```

And here's how I compile it:

```
clang++ -std=c++23 -fsanitize=integer -fno-sanitize-recover=all example.cc -o
example
```

When I run the program, I trigger the `UndefinedBehaviorSanitizer` with the
following error:

```
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/format:3906:66:
runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed)
to type 'size_t' (aka 'unsigned long') changed the value to
18446744073709551615 (64-bit, unsigned)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/format:3906:66
```

Upon checking `/usr/include/c++/14/format`, the error came from the following:

```
namespace __format
{
  /* ... */
  template<typename _CharT>
    struct _Scanner
    {
      /* ... */
      constexpr explicit
      _Scanner(basic_string_view<_CharT> __str, size_t __nargs = -1)
      : _M_pc(__str, __nargs)
      { }
      /* ... */
```

Under normal circumstances, compiling the program will not produce an error.
And according to the standard, `size_t` or `unsigned` numerics
overflow/underflow are well defined.

However, I believe that assigning `-1` to `size_t` is non-sensical. In
addition, I also would like to continue to use `-fsanitize=integer` in my
program development. Therefore, I believe this is both a semantic bug and a bug
for the users of the standard library.

If assigning the `size_t` to the largest possible value is indeed the intended
behavior, please make it explicit by using `std::SIZE_MAX` so that it does not
trigger `UndefinedBehaviorSanitizer`.

Reply via email to