[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