[Bug libstdc++/60734] New: Undefined behavior in g++-v4/bits/stl_tree.h

trippels at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Apr 1 20:24:00 GMT 2014


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60734

            Bug ID: 60734
           Summary: Undefined behavior in g++-v4/bits/stl_tree.h
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: trippels at gcc dot gnu.org

While debugging a gold linker issue I came across the following
-fsanitize=undefined runtime error:

/usr/lib64/gcc/x86_64-pc-linux-gnu/4.9.0/include/g++-v4/bits/stl_tree.h:741:25:
runtime error: downcast of address 0x7fff4c8e1d80 with insufficient space for
an object of type '_Rb_tree_node<std::pair<const std::basic_string<char>,
gold::Output_segment *> >'
0x7fff4c8e1d80: note: pointer points here
 00 00 00 00  00 00 00 00 00 00 00 00  d0 2c 8d 02 00 00 00 00  10 2d 8d 02 00
00 00 00  50 2d 8d 02
              ^ 

      iterator
      end() _GLIBCXX_NOEXCEPT
      { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }

The following message: 
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-August/031213.html
also points to the issue.

Quote:
» _M_header is an _Rb_tree_node_base, which is smaller than an
_Rb_tree_node<_Tp>. Usually, this would be OK -- you can reinterpret_cast
between pointers of different types pretty much arbitrarily -- but because
_Rb_tree_node_base is a base class of _Rb_tree_node<_Tp>, this is a
static_cast, and the ruling wording is 5.2.9/11, which says " If the
prvalue of type “pointer to cv1 B” points
to a B that is actually a subobject of an object of type D, the resulting
pointer points to the enclosing object of type D. Otherwise, the behavior
is undefined."

We've managed to prove that the prvalue of type "pointer to
_Rb_tree_node_base" is not, in fact, a subobject of type
"_Rb_tree_node<_Tp>", because there's not enough room in the allocated
storage for an object of that type at that address. So we've determined
that the behavior is undefined.

This is a bug in libstdc++. The fix is to use reinterpret_cast instead of
static_cast in the definition of 'end'.«

And indeed this fixes the issue for me.


More information about the Gcc-bugs mailing list