<div dir="ltr">This bug appears to be fixed in the Win 10.0.10586.0 SDK:<div><br><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">        if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::<br>            RegMultiply( (unsigned __int64)a1, (unsigned __int64)b1, tmp ) == SafeIntNoError )</blockquote></div><div><br></div><div>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.</div></div><div><br></div><div>Is there a reason LibreOffice uses the 10240 SDK?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Apr 7, 2017 at 12:42 AM, Stephan Bergmann via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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\u<wbr>crt\safeint_internal.h):<br>
<br>
There is a specialization of some LargeIntRegMultiply::RegMultip<wbr>ly<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
template < typename E > class LargeIntRegMultiply< signed __int64, signed __int64, E ><br>
{<br>
public:<br>
    static SafeIntError RegMultiply( const signed __int64& a, const signed __int64& b, signed __int64& ret )<br>
    {<br>
        bool aNegative = false;<br>
        bool bNegative = false;<br>
<br>
        unsigned __int64 tmp;<br>
        __int64 a1 = a;<br>
        __int64 b1 = b;<br>
</blockquote>
...<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
        if( LargeIntRegMultiply< unsigned __int64, unsigned __int64, E >::<br>
            RegMultiply( (unsigned __int64)a1, (unsigned __int64)b1, (unsigned __int64)tmp ) == SafeIntNoError )<br>
        {<br>
</blockquote>
...<br>
<br>
that calls another such specialization (namely<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
template< typename E > class LargeIntRegMultiply< unsigned __int64, unsigned __int64, E ><br>
{<br>
public:<br>
    static SafeIntError RegMultiply( const unsigned __int64& a, const unsigned __int64& b, unsigned __int64& ret )<br>
</blockquote>
...<br>
<br>
for unsigned) which takes its third argument by non-const lvalue-reference.  But what gets passed at the call site above,<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                                                                     (unsigned __int64)tmp<br>
</blockquote>
<br>
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.<br>
<br>
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).<br>
<br>
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)?<br>
<br>
(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:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
#include <iostream><br>
namespace {<br>
    int n = 0;<br>
    void f() { n = 1; }<br>
    int g(int const & n) { f(); return n; }<br>
}<br>
int main() {<br>
    std::cout << g(static_cast<int>(n)) << '\n';<br>
}<br>
</blockquote>
<br>
But who knows.)<br>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
</blockquote></div><br></div>