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?