#1004069 g++-11: AddressSanitizer false positive in std::sort

Package:
g++-11
Source:
gcc-11
Description:
GNU C++ compiler
Submitter:
Németh Gábor
Date:
2022-01-20 09:57:04 UTC
Severity:
normal
#1004069#5
Date:
2022-01-20 09:53:49 UTC
From:
To:
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).