Boost C++ Libraries: Ticket #8489: Unnecessary Definition of iterator_adaptor.hpp class Has Dangerous Return of Temporary Object https://svn.boost.org/trac10/ticket/8489 <p> Change definition of private iterator_adaptor&lt;...&gt;::dereference to a declaration, avoiding illegal return of local temporary object: </p> <blockquote> <p> error: returning reference to local temporary object [-Werror,-Wreturn-stack-address] </p> <blockquote> <p> { return *m_iterator; } </p> </blockquote> </blockquote> <p> Changing to a declaration is semantically acceptable because the preceding comment and a code search shows that the function was made private to ensure it is not used in this base class. </p> <p> This was revealed using Clang++ 3.0.6. It is a showstopper for people required to use Clang with warnings turned in errors. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8489 Trac 1.4.3 Jeffrey D. Oldham <oldham@…> Wed, 24 Apr 2013 00:42:20 GMT attachment set https://svn.boost.org/trac10/ticket/8489 https://svn.boost.org/trac10/ticket/8489 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">iterator_adaptor.hpp.20130423.patch</span> </li> </ul> <p> A patch resolving the problem. </p> Ticket Jeffrey D. Oldham <oldham@…> Wed, 24 Apr 2013 00:42:43 GMT attachment set https://svn.boost.org/trac10/ticket/8489 https://svn.boost.org/trac10/ticket/8489 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">iterator-adaptor.error-program.20130423.cc</span> </li> </ul> <p> Program illustrating the error. </p> Ticket Jeffrey D. Oldham <oldham@…> Wed, 24 Apr 2013 15:25:55 GMT summary changed https://svn.boost.org/trac10/ticket/8489#comment:1 https://svn.boost.org/trac10/ticket/8489#comment:1 <ul> <li><strong>summary</strong> <span class="trac-field-old">Unnecessary Definition of ??? Has Dangerous Return of Temporary Object</span> → <span class="trac-field-new">Unnecessary Definition of iterator_adaptor.hpp class Has Dangerous Return of Temporary Object</span> </li> </ul> Ticket gromer@… Wed, 24 Apr 2013 16:35:32 GMT cc set https://svn.boost.org/trac10/ticket/8489#comment:2 https://svn.boost.org/trac10/ticket/8489#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">gromer@…</span> added </li> </ul> Ticket oldham@… Wed, 24 Apr 2013 19:47:59 GMT <link>https://svn.boost.org/trac10/ticket/8489#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:3</guid> <description> <p> The patch breaks iterator_facade.hpp::iterator_core_access::dereference() so it should not be used. However, the problem still exists for the test case. </p> </description> <category>Ticket</category> </item> <item> <author>oldham@…</author> <pubDate>Wed, 24 Apr 2013 23:45:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8489#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:4</guid> <description> <p> It is not clear if the program showing the error is itself correct. </p> </description> <category>Ticket</category> </item> <item> <author>oldham@…</author> <pubDate>Thu, 25 Apr 2013 14:40:09 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8489#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:5</guid> <description> <p> If my logic is correct, the return type for iterator_adaptor::dereference() is: </p> <ul><li>Reference if Reference != use_default, </li><li>iterator_reference&lt;Base&gt; if Reference == use_default and Value == use_default, </li><li>add_reference&lt;Value&gt; if Reference == use_default and Value != use_default. </li></ul><p> I conjecture </p> <ul><li>the second case is not causing problems and </li><li>the third case is causing problems for the example program. For a slight variant of the program, I believe Value == const char and Reference == use_default. Thus, it tries to return a const char&amp; which causes a local temporary to be created and then a reference returned. </li></ul><p> One possible implementation solution is to specialize iterator_adaptor&lt;&gt; so dereference has a declaration with no definition for the third case. Another is to modify iterator_adaptor_base so problematic third cases do not occur. </p> <p> It is not clear what to do. </p> </description> <category>Ticket</category> </item> <item> <author>james.hirschorn@…</author> <pubDate>Tue, 30 Apr 2013 18:06:11 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8489#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:6</guid> <description> <p> I originally thought this was a bug too, but I do not believe it is. </p> <p> First of all, the dereference member function of iterator_adaptor does not need to be valid (it is clearly invalid in your specific example). You can simply redefine dereference in your iterator class which inherits from iterator_adaptor, and the one from the base class will be ignored by the compiler. </p> <p> Secondly, I supsect there may be a problem with the operator*() of your Base class. It is returning by value, but normally operator*() returns a reference. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Mon, 10 Jun 2013 04:58:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8489#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:7</guid> <description> <p> The problem here is that the underlying iterator of the <code>iterator_adaptor</code> is an <code>istreambuf_iterator&lt;char&gt;</code>, which quite legitimately (for an input iterator) returns a non-reference type from its <code>operator*</code>. This should be filed as a bug against Spirit. </p> <p> To debug it, I applied this patch to iterator_adaptor.hpp, and ran the failing program through stlfilt: </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>iterator_adaptor.hpp</a> </h2> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File iterator_adaptor.hpp 2013-06-09 20:32:52.000000000 -0700"> old </th> <th title="File /Users/dave/src/boost/release/boost_1_53_0/boost/iterator/iterator_adaptor.hpp 2013-06-09 21:42:48.000000000 -0700"> new </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>18</th><th>18</th><td class="l"><span>#include &lt;boost/mpl/and.hpp&gt;</span></td> </tr> <tr> <th>19</th><th>19</th><td class="l"><span>#include &lt;boost/mpl/not.hpp&gt;</span></td> </tr> <tr> <th>20</th><th>20</th><td class="l"><span>#include &lt;boost/mpl/or.hpp&gt;</span></td> </tr> </tbody> <tbody class="add"> <tr class="last first"> <th>&nbsp;</th><th>21</th><td class="r"><ins>#include &lt;boost/mpl/assert.hpp&gt;</ins></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>21</th><th>22</th><td class="l"><span></span></td> </tr> <tr> <th>22</th><th>23</th><td class="l"><span>#include &lt;boost/type_traits/is_same.hpp&gt;</span></td> </tr> <tr> <th>23</th><th>24</th><td class="l"><span>#include &lt;boost/type_traits/is_convertible.hpp&gt;</span></td> </tr> </tbody> <tbody class="add"> <tr class="last first"> <th>&nbsp;</th><th>25</th><td class="r"><ins>#include &lt;boost/type_traits/is_reference.hpp&gt;</ins></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>24</th><th>26</th><td class="l"><span></span></td> </tr> <tr> <th>25</th><th>27</th><td class="l"><span>#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY</span></td> </tr> <tr> <th>26</th><th>28</th><td class="l"><span># include &lt;boost/type_traits/remove_reference.hpp&gt;</span></td> </tr> </tbody> <tbody class="skipped"> <tr> <th><a href="#L303">&hellip;</a></th> <th><a href="#L305">&hellip;</a></th> <td> <em></em> &nbsp; </td> </tr> </tbody> <tbody class="unmod"> <tr> <th>303</th><th>305</th><td class="l"><span>&nbsp; &nbsp; &nbsp; // base_reference(), above, to get direct access to m_iterator.</span></td> </tr> <tr> <th>304</th><th>306</th><td class="l"><span>&nbsp; &nbsp; &nbsp; // </span></td> </tr> <tr> <th>305</th><th>307</th><td class="l"><span>&nbsp; &nbsp; &nbsp; typename super_t::reference dereference() const</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>306</th><th>&nbsp;</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; { return *m_iterator; }</span></td> </tr> <tr> <th>&nbsp;</th><th>308</th><td class="r"><span>&nbsp; &nbsp; &nbsp; {</span></td> </tr> <tr> <th>&nbsp;</th><th>309</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BOOST_MPL_ASSERT((</span></td> </tr> <tr> <th>&nbsp;</th><th>310</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mpl::or_&lt;</span></td> </tr> <tr> <th>&nbsp;</th><th>311</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mpl::not_&lt;is_reference&lt;typename super_t::reference&gt; &gt;</span></td> </tr> <tr> <th>&nbsp;</th><th>312</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , is_reference&lt;</span></td> </tr> <tr> <th>&nbsp;</th><th>313</th><td class="r"><span>#ifdef BOOST_NO_CXX11_DECLTYPE</span></td> </tr> <tr> <th>&nbsp;</th><th>314</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; typename boost::iterator_reference&lt;Base&gt;::type</span></td> </tr> <tr> <th>&nbsp;</th><th>315</th><td class="r"><span>#else </span></td> </tr> <tr> <th>&nbsp;</th><th>316</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; decltype(*m_iterator)</span></td> </tr> <tr> <th>&nbsp;</th><th>317</th><td class="r"><span>#endif </span></td> </tr> <tr> <th>&nbsp;</th><th>318</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &gt;</span></td> </tr> <tr> <th>&nbsp;</th><th>319</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &gt;));</span></td> </tr> <tr> <th>&nbsp;</th><th>320</th><td class="r"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return *m_iterator; </span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>321</th><td class="r"><span>&nbsp; &nbsp; &nbsp; }</span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>307</th><th>322</th><td class="l"><span></span></td> </tr> <tr> <th>308</th><th>323</th><td class="l"><span>&nbsp; &nbsp; &nbsp; template &lt;</span></td> </tr> <tr> <th>309</th><th>324</th><td class="l"><span>&nbsp; &nbsp; &nbsp; class OtherDerived, class OtherIterator, class V, class C, class R, class D</span></td> </tr> </tbody> </table> </li> </ul> </div></div> </description> <category>Ticket</category> </item> <item> <dc:creator>Dave Abrahams</dc:creator> <pubDate>Mon, 10 Jun 2013 05:37:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8489#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8489#comment:8</guid> <description> <p> I take it back; this isn't a Spirit bug… yet. The error is in the user program. As <a href="http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/support/multi_pass.html">http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/spirit/support/multi_pass.html</a> makes quite clear, Spirit works only with <strong>forward</strong> iterators. It's not clear at all, however, why I'm unable to solve the problem by wrapping the <code>istreambuf_iterator</code> with Spirit's <code>multi_pass</code>. See <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3999" title="#3999: Bugs: multi_pass cannot deal with all input iterators (closed: fixed)">#3999</a> </p> </description> <category>Ticket</category> </item> </channel> </rss>