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?

Reply via email to