Boost C++ Libraries: Ticket #11942: split_interval_set incorrect works compiled with clang https://svn.boost.org/trac10/ticket/11942 <p> I have a very basic program for demostration </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/icl/split_interval_set.hpp&gt;</span><span class="cp"></span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">boost</span><span class="o">::</span><span class="n">icl</span><span class="o">::</span><span class="n">split_interval_set</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">intervals</span><span class="p">;</span> <span class="n">intervals</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">icl</span><span class="o">::</span><span class="n">discrete_interval</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">));</span> <span class="n">intervals</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">icl</span><span class="o">::</span><span class="n">discrete_interval</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">));</span> <span class="n">intervals</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">boost</span><span class="o">::</span><span class="n">icl</span><span class="o">::</span><span class="n">discrete_interval</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">));</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">intervals</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> clang++ -I ./boost/include a.cpp; </p> <p> When compiled with clang on Mac the output is 2 and not 3 as it should. The worst thing is that it's not only produces invalid result but also corrupts memory so that execution of some code after the code provided leads to a crash with BAD_ACCESS exception. </p> <p> The problem first appears in version 1.56. The above program prints "3" on 1.55. And it's still present on master. It actually was introduced with this commit <a class="ext-link" href="https://github.com/boostorg/icl/commit/d6e037756f2c062fba703c5f48800ee577052f72"><span class="icon">​</span>https://github.com/boostorg/icl/commit/d6e037756f2c062fba703c5f48800ee577052f72</a> </p> <p> Spent some time on debugging the issue with Xcode and it appears that the problem is in interval_base_set.hpp::add_segment </p> <div class="wiki-code"><div class="code"><pre> <span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">SubType</span><span class="p">,</span> <span class="k">class</span> <span class="nc">DomainT</span><span class="p">,</span> <span class="n">ICL_COMPARE</span> <span class="n">Compare</span><span class="p">,</span> <span class="n">ICL_INTERVAL</span><span class="p">(</span><span class="n">ICL_COMPARE</span><span class="p">)</span> <span class="n">Interval</span><span class="p">,</span> <span class="n">ICL_ALLOC</span> <span class="n">Alloc</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="kt">void</span> <span class="n">interval_base_set</span><span class="o">&lt;</span><span class="n">SubType</span><span class="p">,</span><span class="n">DomainT</span><span class="p">,</span><span class="n">Compare</span><span class="p">,</span><span class="n">Interval</span><span class="p">,</span><span class="n">Alloc</span><span class="o">&gt;</span> <span class="o">::</span><span class="n">add_segment</span><span class="p">(</span><span class="k">const</span> <span class="n">interval_type</span><span class="o">&amp;</span> <span class="n">inter_val</span><span class="p">,</span> <span class="n">iterator</span><span class="o">&amp;</span> <span class="n">it_</span><span class="p">)</span> <span class="p">{</span> <span class="n">interval_type</span> <span class="n">lead_gap</span> <span class="o">=</span> <span class="n">right_subtract</span><span class="p">(</span><span class="n">inter_val</span><span class="p">,</span> <span class="o">*</span><span class="n">it_</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">icl</span><span class="o">::</span><span class="n">is_empty</span><span class="p">(</span><span class="n">lead_gap</span><span class="p">))</span> <span class="c1">// [lead_gap--- . . .</span> <span class="c1">// [prior_) [-- it_ ...</span> <span class="k">this</span><span class="o">-&gt;</span><span class="n">_set</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">prior</span><span class="p">(</span><span class="n">it_</span><span class="p">),</span> <span class="n">lead_gap</span><span class="p">);</span> <span class="c1">// . . . --------- . . . addend interval</span> <span class="c1">// [-- it_ --) has a common part with the first overval</span> <span class="o">++</span><span class="n">it_</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> this-&gt;_set.insert(<strong>prior(it_)</strong>, lead_gap); And it happens on attempt to insert interval at the begging of the set <em>it_</em> is an iterator pointing to the first element in the set so <em>prior(it_)</em> ( e.g. --it_) is actually undefined and contains some garbage on Mac </p> <p> I wasn't able to reproduce the same behavior with gcc linux compiler but once I build it with -D_GLIBCXX_DEBUG option (enables safe iterators) </p> <p> g++ -D_GLIBCXX_DEBUG -v -g --std=c++11 -I ./boost/ ./a.cpp </p> <p> The output from the program was following </p> <pre class="wiki">/usr/include/c++/4.8/debug/safe_iterator.h:323:error: attempt to decrement a dereferenceable (start-of-sequence) iterator. Objects involved in the operation: iterator "this" @ 0x0x7fff70b855a0 { type = N11__gnu_debug14_Safe_iteratorISt23_Rb_tree_const_iteratorIN5boost3icl17discrete_intervalIiSt4lessEEENSt7__debug3setIS6_NS3_19exclusive_less_thanIS6_EESaIS6_EEEEE (mutable iterator); state = dereferenceable (start-of-sequence); references sequence with type `NSt7__debug3setIN5boost3icl17discrete_intervalIiSt4lessEENS2_19exclusive_less_thanIS5_EESaIS5_EEE' @ 0x0x7fff70b855a0 } Aborted (core dumped) </pre><p> So all above demonstrates that the problem really exists. </p> <p> As for the solution, the suggest is just remove prior fuction call, and provide it_ as the first argument to insert The hint still will be correct, and for c++11 that's even better. </p> <pre class="wiki">hint - iterator, used as a suggestion as to where to start the search (until C++11) iterator to the position before which the new element will be inserted (since C++11) </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11942 Trac 1.4.3 Joachim Faulhaber Tue, 19 Jun 2018 13:39:23 GMT status, milestone changed; cc, resolution set https://svn.boost.org/trac10/ticket/11942#comment:1 https://svn.boost.org/trac10/ticket/11942#comment:1 <ul> <li><strong>cc</strong> <span class="trac-author">Joachim Faulhaber</span> added </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.68.0</span> </li> </ul> Ticket