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

            Bug ID: 118493
           Summary: std::vector::insert regression in C++03: execution
                    reaches an unreachable program point
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: arseny.kapoulkine at gmail dot com
  Target Milestone: ---

Created attachment 60163
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=60163&action=edit
reproducer

The following patch
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=955202eb2cdbe2bc74c626bce90ee1eac410ad4f
adds this line:

+               if (__len < (__n + (__old_start - __old_finish)))

... which is incorrect, as "start - finish" subtraction order is wrong - it
should be "finish - start".

The consequences are that insert will trap in some cases depending on how many
elements the vector already has and how many elements are being inserted. For
example, if the vector size and capacity is 768 elements, and 384 elements
(__n) are being inserted, __len computed via _M_check_len(__n) produces 1536
(doubling the currently allocated capacity). Since __n is 384, __n + (-768)
underflows and produces a very large value that is definitely greater then
__len. Depending on the codegen the trap may or may not happen; it does happen
when building with -fsanitize=undefined without optimizations at least.

This is part of gcc 14 release; I can only imagine this doesn't break the world
because the world generally isn't compiling for C++ versions earlier than 2011
these days.

To reproduce, compile and run the attached file as follows:

g++ test.cpp -std=c++03 -fsanitize=undefined && ./a.out

Reply via email to