[cfe-commits] [Patch] Implement compiler intrinsics for MSVC 2012 type_traits

Richard Smith richard at metafoo.co.uk
Fri Nov 9 21:13:34 PST 2012


On Thu, Nov 8, 2012 at 5:49 PM, Ryan Molden <ryanmolden at gmail.com> wrote:
> This is a re-submission of an older proposed patch
> (http://www.mail-archive.com/cfe-commits@cs.uiuc.edu/msg55616/0001-Added-support-for-MSVC-2012-type-traits-used-in-stan.patch)
> that João hadn't had time to write tests for (which were requested with the
> original submission review).
>
> The only changes I made from the original (apart from adding tests) was to
> take out the bail-out for hasTrivialMoveAssignment from
> UTT_HasNothrowMoveAssign in EvaluateUnaryTypeTrait (in
> lib\Sema\SemaExprCXX.cpp).
>
> My reasoning was that trivial move assignment operators (which I understand
> to be implicitly generated ones, please correct me if this is mistaken) can
> actually have non-empty exception specifiers if any of the member
> move-assignment operators they invoke have such non-empty exception
> specifiers.
>
> Specifically:
>
> n3376 15.4 [except.spec]/14
>
> An inheriting constructor (12.9) and an implicitly declared special member
> function (Clause 12) have an exception-specification. If f is an inheriting
> constructor or an implicitly declared default constructor, copy constructor,
> move constructor, destructor, copy assignment operator, or move assignment
> operator, its implicit exception-specification specifies the type-id T if
> and only if T is allowed by the exception-specification of a function
> directly invoked by f’s implicit definition; f allows all exceptions if any
> function it directly invokes allows all exceptions, and f has the
> exception-specification noexcept(true) if every function it directly invokes
> allows no exceptions. [ Note: An instantiation of an inheriting constructor
> template has an implied exception-specification as if it were a non-template
> inheriting constructor.]
>
> so I would expect this class (HasMemberThrowMoveAssign) to fail for
> std::is_nothrow_move_assignable:
>
> struct NonPOD { NonPOD(int); }; enum Enum { EV }; struct POD { Enum e; int
> i; float f; NonPOD* p; };
>
> struct HasThrowMoveAssign { HasThrowMoveAssign& operator =(const
> HasThrowMoveAssign&&) throw(POD); };
> struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; };
>
> even though it should have a trivial move-assignment operator generated.
> Please correct me if I am mistaken here as my standards reading FU is...not
> strong.

You are mistaken here ;-)

HasMemberThrowMoveAssign's move assignment is not trivial because it
calls a non-trivial move assignment operator. It is possible to have a
throwing trivial move assignment operator, but only if it is deleted.
In that case, the trait should presumbly return false.




More information about the cfe-commits mailing list