https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120915
--- Comment #2 from Cristian Morales Vega <christian.morales.vega at gmail dot com> --- I probably did a mistake before, because I couldn't reproduce it when simplifing it. The thing is actually just ``` #include <cstddef> class stream { char* p_; char* end_; public: stream( char* data, std::size_t size) noexcept : p_(data) , end_(data + size) { } size_t remain() const noexcept { return end_ - p_; } }; int main() { char buf[BUFFER_SIZE]; auto value = stream(&buf[0], BUFFER_SIZE); value.remain(); } ``` ``` bash-5.2# g++ -g -o test_4096 test.cpp -fsanitize=address -fsanitize=pointer-subtract -DBUFFER_SIZE=4096 bash-5.2# g++ -g -o test_2048 test.cpp -fsanitize=address -fsanitize=pointer-subtract -DBUFFER_SIZE=2048 bash-5.2# ASAN_OPTIONS="detect_invalid_pointer_pairs=1" ./test_2048 bash-5.2# ASAN_OPTIONS="detect_invalid_pointer_pairs=1" ./test_4096 ================================================================= ==21215==ERROR: AddressSanitizer: invalid-pointer-pair: 0x73179da01040 0x73179da00040 #0 0x0000004006e3 in stream::remain() const /test/test.cpp:20 #1 0x000000400599 in main /test/test.cpp:28 #2 0x77179f5cc5f4 in __libc_start_call_main (/lib64/libc.so.6+0x35f4) (BuildId: 7504db94dbf054e06eaac49950f57161c601f5c6) #3 0x77179f5cc6a7 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x36a7) (BuildId: 7504db94dbf054e06eaac49950f57161c601f5c6) #4 0x000000400404 in _start (/test/test_4096+0x400404) (BuildId: 6bfacb1c660c8a6afb3d50657a62ee65e44c4353) Address 0x73179da01040 is located in stack of thread T0 at offset 4160 in frame #0 0x0000004004d5 in main /test/test.cpp:25 This frame has 2 object(s): [32, 48) 'value' (line 27) [64, 4160) 'buf' (line 26) <== Memory access at offset 4160 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) Address 0x73179da00040 is located in stack of thread T0 at offset 64 in frame #0 0x0000004004d5 in main /test/test.cpp:25 This frame has 2 object(s): [32, 48) 'value' (line 27) [64, 4160) 'buf' (line 26) <== Memory access at offset 64 is inside this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions *are* supported) SUMMARY: AddressSanitizer: invalid-pointer-pair /test/test.cpp:20 in stream::remain() const ==21215==ABORTING ``` So... sure, technically "one after the last" is a different object. But isn't it valid (seems like a common idiom in C++)? And why does it complain with a 4096 buffer, but not with a 2048 bytes one?