<br><br><div class="gmail_quote">On Fri, Nov 9, 2012 at 9:13 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Thu, Nov 8, 2012 at 5:49 PM, Ryan Molden <<a href="mailto:ryanmolden@gmail.com">ryanmolden@gmail.com</a>> wrote:<br>
> This is a re-submission of an older proposed patch<br>
> (<a href="http://www.mail-archive.com/cfe-commits@cs.uiuc.edu/msg55616/0001-Added-support-for-MSVC-2012-type-traits-used-in-stan.patch" target="_blank">http://www.mail-archive.com/cfe-commits@cs.uiuc.edu/msg55616/0001-Added-support-for-MSVC-2012-type-traits-used-in-stan.patch</a>)<br>

> that João hadn't had time to write tests for (which were requested with the<br>
> original submission review).<br>
><br>
> The only changes I made from the original (apart from adding tests) was to<br>
> take out the bail-out for hasTrivialMoveAssignment from<br>
> UTT_HasNothrowMoveAssign in EvaluateUnaryTypeTrait (in<br>
> lib\Sema\SemaExprCXX.cpp).<br>
><br>
> My reasoning was that trivial move assignment operators (which I understand<br>
> to be implicitly generated ones, please correct me if this is mistaken) can<br>
> actually have non-empty exception specifiers if any of the member<br>
> move-assignment operators they invoke have such non-empty exception<br>
> specifiers.<br>
><br>
> Specifically:<br>
><br>
> n3376 15.4 [except.spec]/14<br>
><br>
> An inheriting constructor (12.9) and an implicitly declared special member<br>
> function (Clause 12) have an exception-specification. If f is an inheriting<br>
> constructor or an implicitly declared default constructor, copy constructor,<br>
> move constructor, destructor, copy assignment operator, or move assignment<br>
> operator, its implicit exception-specification specifies the type-id T if<br>
> and only if T is allowed by the exception-specification of a function<br>
> directly invoked by f’s implicit definition; f allows all exceptions if any<br>
> function it directly invokes allows all exceptions, and f has the<br>
> exception-specification noexcept(true) if every function it directly invokes<br>
> allows no exceptions. [ Note: An instantiation of an inheriting constructor<br>
> template has an implied exception-specification as if it were a non-template<br>
> inheriting constructor.]<br>
><br>
> so I would expect this class (HasMemberThrowMoveAssign) to fail for<br>
> std::is_nothrow_move_assignable:<br>
><br>
> struct NonPOD { NonPOD(int); }; enum Enum { EV }; struct POD { Enum e; int<br>
> i; float f; NonPOD* p; };<br>
><br>
> struct HasThrowMoveAssign { HasThrowMoveAssign& operator =(const<br>
> HasThrowMoveAssign&&) throw(POD); };<br>
> struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; };<br>
><br>
> even though it should have a trivial move-assignment operator generated.<br>
> Please correct me if I am mistaken here as my standards reading FU is...not<br>
> strong.<br>
<br>
</div></div>You are mistaken here ;-)<br>
<br>
HasMemberThrowMoveAssign's move assignment is not trivial because it<br>
calls a non-trivial move assignment operator. It is possible to have a<br>
throwing trivial move assignment operator, but only if it is deleted.<br>
In that case, the trait should presumbly return false.<br>
</blockquote></div><br><div>Great, thanks for the catch. So it seems that having the early bail-out for things with trivial move assignment operators is correct. I put it back in and all tests are still passing (I thought one of them was failing before I took it out, but that was a week+ ago, so perhaps I am just mis-remembering).</div>
<div><br></div><div>It isn't clear how I would make a 'throwing trivial move assignment operator', if you have suggestions I can certainly add a test for it.</div><div><br></div><div>New patch attached that simply syncs to tip and adds back the bail-out for types with a trivial move-assignment operator.</div>
<div><br></div><div>Ryan</div>