https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127333
Bug ID: 127333
Summary: __builtin_dynamic_object_size truncates a signed
counted_by count to 32 bits, bypassing FORTIFY=3
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: 220255623 at seu dot edu.cn
CC: 220245569 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Created attachment 65561
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65561&action=edit
Minimal signed counted_by object-size trigger.
Summary
-------
GCC 16.1.0 computes the wrong dynamic object size for a signed
`counted_by` count wider than `int`. The negative-count clamp in
`gcc/tree-object-size.cc::access_with_size_object_size` uses
`integer_type_node`, narrowing the count to 32-bit `int` before it is
converted to `sizetype`.
Reproducer
----------
Build the attached `trigger.i` with:
gcc -O2 -D_FORTIFY_SOURCE=3 -Wall -Wextra trigger.i -o trigger
./trigger
Expected:
n=0x80000000 bdos=2147483648 expected=2147483648
n=0x100000000 bdos=4294967296 expected=4294967296
Actual with GCC 16.1.0 on x86_64-pc-linux-gnu:
n=0x80000000 bdos=18446744071562067968 expected=2147483648
n=0x100000000 bdos=0 expected=4294967296
The `0x80000000` value becomes `INT_MIN` and is sign-extended by the
conversion to `sizetype`; `0x100000000` loses its upper 32 bits. The
same failure is present in tested GCC 15.2.0, 16.0.1 prerelease, and
GCC 17.0 development snapshots. Unsigned counts are unaffected. No
passing version was tested, so this is not marked as a regression.