[Bug c++/70035] [5 Regression] Calling a non-virtual member in base-class constructor call with ubsan causes segfault when superclass has virtual member with same name

bernd.edlinger at hotmail dot de gcc-bugzilla@gcc.gnu.org
Sun Mar 13 13:58:00 GMT 2016


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70035

Bernd Edlinger <bernd.edlinger at hotmail dot de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bernd.edlinger at hotmail dot de

--- Comment #9 from Bernd Edlinger <bernd.edlinger at hotmail dot de> ---
(In reply to Jakub Jelinek from comment #8)
> Fixed for g++ 6+ so far.

no. this creates a new problem.
I see now crashes in valid code that uses the std::stringstream
when -fsanitize=undefined is used.
Unfortunately I was not able to reduce the test case.

But what is wrong can be seen with this simple test case:

cat test.cc
#include <sstream>

main(int argc, char** argv)
{
  std::stringstream ss;
  ss << "test";
  for (int i=0; i<argc; i++)
    ss << argv[i];
  __builtin_printf("%s\n", ss.str().c_str());
}

gcc -O3 -fsanitize=undefined -fdump-tree-gimple

look at std::basic_iostream<_CharT, _Traits>::basic_iostream():
  UBSAN_NULL (this, 2B, 8);
  MEM[(struct  &)this] = {CLOBBER};
  this->D.34679._vptr.basic_istream = 0B;      <= set _vptr to zero
  D.40658 = this->D.34679._vptr.basic_istream; <= D.40658 is null
  D.40659 = D.40658 + 18446744073709551592;    <= D.40659 is 0 + -24
  D.40660 = MEM[(long int *)D.40659];          <= will crash if executed
  D.40661 = (sizetype) D.40660;
  D.40662 = this + D.40661;
  D.40662->D.31841._vptr.ios_base = 0B;
  this->D.34680._vptr.basic_ostream = 0B;


However in most of the cases this garbage is removed by optimization.


More information about the Gcc-bugs mailing list