Boost C++ Libraries: Ticket #11582: Regression with -Woverloaded-virtual in unit_test_log_t https://svn.boost.org/trac10/ticket/11582 <p> While trying to compile my code with "-Woverloaded-virtual -Werror", I found a shortcoming, possibly even a bug. </p> <p> In 1.59.0 (and, as far as I can see in git, all following versions), there are the following declarations/definitions: </p> <pre class="wiki">class test_observer /* boost/test/tree/observer.hpp:40 */ virtual void test_unit_skipped( test_unit const&amp; tu, const_string) { test_unit_skipped( tu ); } virtual void test_unit_skipped( test_unit const&amp; ) {} ///&lt; backward compartibility class unit_test_log_t /* boost/test/unit_test_log.hpp:97 */ virtual void test_unit_skipped( test_unit const&amp;, const_string ); /* Actually uses the message in the implementation */ /* Does not override Test_unit_skipped( test_unit const&amp; ) */ </pre><p> The problem with this code is that code like the following simply will not work: </p> <pre class="wiki">unit_test_log_t&amp; foobar; test_unit const&amp; tu; foobar.test_unit_skipped( tu ); // &lt;-- Error! </pre><p> g++ would say "candidate expects 2 arguments, 1 provided". clang++ is a tad more helpful, and would say: "too few arguments to function call, expected 2, have 1; did you mean 'test_observer::test_unit_skipped'?" In case you're unfamiliar with that behaviour, see this specific answer: <a class="ext-link" href="http://stackoverflow.com/a/6035884/3070326"><span class="icon">​</span>http://stackoverflow.com/a/6035884/3070326</a> (Error messages are from a different compilation, but should be the same.) </p> <p> I hope I have now established that -Woverloaded-virtual "has a point". </p> <p> I don't fully understand why unit_test_log_t doesn't override the other signature, too; but it should be easily possible to override it with something like: </p> <pre class="wiki">test_unit_skipped( tu, "&lt;No message&gt;" ); </pre><p> However, I do not yet fully understand the context of unit_test_log_t, so maybe such a call cannot occur. That's why I'm unable to make a patch from that idea. </p> <p> At the very least, this issue is annoying for people who use Boost.Test and try to compile with -Woverloaded-virtual. </p> <p> Note that Boost.Test 1.58.0 did *not* exhibit this issue, so I felt free to put "regression" in the subject and 'severity'. </p> <p> (PS: Thanks to Rene Rivera for redirecting me away from the mailing list, and Raffi Enficiaud for redirecting me to this trac.) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11582 Trac 1.4.3 Ben Wiederhake <Ben.Wiederhake@…> Wed, 26 Aug 2015 20:53:50 GMT attachment set https://svn.boost.org/trac10/ticket/11582 https://svn.boost.org/trac10/ticket/11582 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">error_message.log</span> </li> </ul> <p> Verbatim compiler error message </p> Ticket Ben Wiederhake <Ben.Wiederhake@…> Sun, 30 Aug 2015 11:49:53 GMT <link>https://svn.boost.org/trac10/ticket/11582#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11582#comment:1</guid> <description> <p> This seems to be the relevant part of the inheritance hierarchy: </p> <pre class="wiki">test_observer (observer.hpp) :// No superclasses virtual void test_unit_skipped( test_unit const&amp; tu, const_string ) { test_unit_skipped( tu ); } virtual void test_unit_skipped( test_unit const&amp; ) {} ///&lt; backward compartibility unit_test_log_t (unit_test_log.hpp) : test_observer virtual void test_unit_skipped( test_unit const&amp;, const_string ); // Actual implementation, forwards 'reason' argument as-is to a log_formatter progress_monitor_t (progress_monitor.hpp) : test_observer virtual void test_unit_skipped( test_unit const&amp;, const_string ); // Actual implementation, ignores 'reason' argument results_collector_t (results_collector.hpp) : test_observer virtual void test_unit_skipped( test_unit const&amp;, const_string ); // Actual implementation, ignores 'reason' argument // No further implementations of 'test_observer' </pre><p> So I suggest to do the following things: </p> <ul><li>The signatures of <code>progress_monitor_t</code> and <code>results_collector_t</code> remove the <code>reason</code> argument in their respective method's signature. </li><li>The classes <code>progress_monitor_t</code> and <code>results_collector_t</code> are completed by a method <code>virtual void test_unit_skipped( test_unit const&amp; tu, const_string ) { test_unit_skipped( tu ); }</code> each. </li><li>The class <code>unit_test_log_t</code> is completed by a method <code>virtual void test_unit_skipped( test_unit const&amp; ) { test_unit_skipped( tu, const_string("&lt;Unknown reason&gt;") ); }</code> or something like that. </li></ul><p> Plus, of course, a few tests to make sure that now the signatures <code>test_unit_skipped(test_unit const&amp;)</code> <strong>and</strong> <code>test_unit_skipped(test_unit const&amp;, const_string)</code> are available to all instances. </p> <p> I'd love to hear why this is a good / bad idea. </p> </description> <category>Ticket</category> </item> <item> <author>Ben Wiederhake <Ben.Wiederhake@…></author> <pubDate>Sun, 30 Aug 2015 17:05:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11582#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11582#comment:2</guid> <description> <p> Here's a pull request in order to provide grounds for discussion: <a class="ext-link" href="https://github.com/boostorg/test/pull/85"><span class="icon">​</span>https://github.com/boostorg/test/pull/85</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Gennadiy Rozental</dc:creator> <pubDate>Mon, 31 Aug 2015 00:59:28 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11582#comment:3 https://svn.boost.org/trac10/ticket/11582#comment:3 <ul> <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">wontfix</span> </li> </ul> <p> This warning makes no sense in this case. The code is doing the right thing. </p> <p> foobar.test_unit_skipped( tu ); is not supposed to work. New Boost.Test code always passes reason why test unit is skipped. The other function only exists to work around the case when someone else outside of Boost.Test implemented test observer based on old semantic. In this case they do not provide 2 arg version and we redirect to one arg version. </p> <p> I'll incorporate you typo fixes. </p> <p> Also compile only tests implemented differently in boost. </p> Ticket