[cfe-dev] clang-cl issue with MSVC's safeint.h and cast-to-self prvalue-ness

Reid Kleckner via cfe-dev cfe-dev at lists.llvm.org
Fri Apr 7 08:57:20 PDT 2017


This bug appears to be fixed in the Win 10.0.10586.0 SDK:

        if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::
>             RegMultiply( (unsigned __int64)a1, (unsigned __int64)b1, tmp )
> == SafeIntNoError )


>From the blog posts I see about safeint, it sounds like it's supposed to be
a portable to many platforms and compilers, so I think we can rely on
Microsoft to keep fixing bugs in this header.

Is there a reason LibreOffice uses the 10240 SDK?

On Fri, Apr 7, 2017 at 12:42 AM, Stephan Bergmann via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> I came across the following problem with clang-cl (in the context of
> compiling LibreOffice) when using the MSVC-provided safeint.h (resp. its
> safeinit_internal.h helper; on my machine located at C:\Program Files
> (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\safeint_internal.h):
>
> There is a specialization of some LargeIntRegMultiply::RegMultiply
>
> template < typename E > class LargeIntRegMultiply< signed __int64, signed
>> __int64, E >
>> {
>> public:
>>     static SafeIntError RegMultiply( const signed __int64& a, const
>> signed __int64& b, signed __int64& ret )
>>     {
>>         bool aNegative = false;
>>         bool bNegative = false;
>>
>>         unsigned __int64 tmp;
>>         __int64 a1 = a;
>>         __int64 b1 = b;
>>
> ...
>
>>
>>         if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::
>>             RegMultiply( (unsigned __int64)a1, (unsigned __int64)b1,
>> (unsigned __int64)tmp ) == SafeIntNoError )
>>         {
>>
> ...
>
> that calls another such specialization (namely
>
> template< typename E > class LargeIntRegMultiply< unsigned __int64,
>> unsigned __int64, E >
>> {
>> public:
>>     static SafeIntError RegMultiply( const unsigned __int64& a, const
>> unsigned __int64& b, unsigned __int64& ret )
>>
> ...
>
> for unsigned) which takes its third argument by non-const
> lvalue-reference.  But what gets passed at the call site above,
>
>
>>  (unsigned __int64)tmp
>>
>
> is the result of needlessly casting tmp (which is already of type unsigned
> __int64), which shall produce a prvalue, which in turn cannot bind to a
> non-const lvalue-reference.  So compiling that with clang-cl fails.
>
> But with MSVC (at least 2013--2017) it succeeds.  That compiler apparently
> has a bug or mis-feature so that the result of casting an lvalue to its own
> type produces an lvalue instead of a prvalue.  (As verified, at least for
> C-style cast and static_cast, and at least if the type is some integral
> type).
>
> Do we have some contact into the MSVC compiler group, so we can clarify
> whether that behavior is considered a mis-feature (so we would want to
> mimic it in some way in clang-cl, at least when compiling the MSVC-provided
> safeint.h) or a bug (so MSVC would want to fix their safeint.h, and we
> probably wouldn't want to duplicate that misbehavior in clang-cl)?
>
> (I would assume it is a genuine bug, which that sloppy safeint_internal.h
> just happens to rely on by accident, as it makes the below program behave
> in an IMO non-conforming way by printing 1 instead of 0:
>
> #include <iostream>
>> namespace {
>>     int n = 0;
>>     void f() { n = 1; }
>>     int g(int const & n) { f(); return n; }
>> }
>> int main() {
>>     std::cout << g(static_cast<int>(n)) << '\n';
>> }
>>
>
> But who knows.)
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170407/d3887b81/attachment.html>


More information about the cfe-dev mailing list