Dear Maintainer,
% cat cc.cc
// For some combinations of
// - the type of inner::a
// - the array size of inner::a
// - the size of the std::array in main
// AddressSanitizer gives a pointer comparison error when calling
std::sort.
// Clearly, it is sensitive to sizeof(outer) but I couldn't reduce to
the exact byte count.
//
// It also runs without failure if the run-time flags are built into the
executeble with:
// const char *__asan_default_options() { return
"detect_invalid_pointer_pairs=2"; }
#include <array>
#include <algorithm>
struct inner {
int a[39];// OK for 38 or less if size of std::array is 13
// double a[10];// OK for 9 or less if size of std::array is 24
constexpr bool operator<(const inner &o) const { return a[0] < o.a[0];
}
};
struct outer {
char dummy;// If this member is not here, then no errors from ASAN
inner i;
constexpr bool operator <(const outer &o) const noexcept {return
o.i<i;}
};
int main(){
std::array<outer, 13> a;// 24 for a double inner::a
std::sort(a.begin(), a.end());
return 0;
}
% g++ -std=c++20 -fno-omit-frame-pointer -fsanitize=address
-fsanitize=pointer-subtract cc.cc
% ASAN_OPTIONS="detect_invalid_pointer_pairs=2" ./a.out
=================================================================
==1663139==ERROR: AddressSanitizer: invalid-pointer-pair: 0x7ffe40fb9dc0
0x7ffe40fb95a0
#0 0x55e1cde17591 in void std::__sort<outer*,
__gnu_cxx::__ops::_Iter_less_iter>(outer*, outer*,
__gnu_cxx::__ops::_Iter_less_iter) (/tmp/a.out+0x1591)
#1 0x55e1cde174d1 in void std::sort<outer*>(outer*, outer*)
(/tmp/a.out+0x14d1)
#2 0x55e1cde172d7 in main (/tmp/a.out+0x12d7)
#3 0x7f80ce3ea7ec in __libc_start_main ../csu/libc-start.c:332
#4 0x55e1cde17149 in _start (/tmp/a.out+0x1149)
Address 0x7ffe40fb9dc0 is located in stack of thread T0 at offset 2112
in frame
#0 0x55e1cde17218 in main (/tmp/a.out+0x1218)
This frame has 1 object(s):
[32, 2112) 'a' (line 23) <== Memory access at offset 2112 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 0x7ffe40fb95a0 is located in stack of thread T0 at offset 32 in
frame
#0 0x55e1cde17218 in main (/tmp/a.out+0x1218)
This frame has 1 object(s):
[32, 2112) 'a' (line 23) <== Memory access at offset 32 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 (/tmp/a.out+0x1591) in
void std::__sort<outer*, __gnu_cxx::__ops::_Iter_less_iter>(outer*,
outer*, __gnu_cxx::__ops::_Iter_less_iter)
==1663139==ABORTING
Here comes my system info, althought I checked and the same error
happens in all of Debian Bookworm (g++ 11.2), Bullseye (g++ 10.2),
Ubuntu Impish (g++ 11.2), Hirsute (g++ 10.3), and Focal (g++ 9.3).