[Libreoffice] [PUSHED] [REVIEW 3-4] Fix for fdo#39589

Lionel Elie Mamane lionel at mamane.lu
Thu Nov 24 01:56:57 PST 2011


On Thu, Nov 24, 2011 at 02:13:57AM -0500, Kohei Yoshida wrote:
> On Thu, 2011-11-24 at 07:50 +0100, Lionel Elie Mamane wrote:
>> On Wed, Nov 23, 2011 at 06:53:53PM -0500, Kohei Yoshida wrote:

>>> I'd like to have

>>> http://cgit.freedesktop.org/libreoffice/core/commit/?id=0215f8b19451ab67c7fdaf91f2da8298a9b89c47

>>> cherry-picked to the 3-4 branch.  It fixes

>> I see how ulimit_cast is the wrong choice there, but:

>> If I understand well, static_cast<unsigned int>(a) where a is a signed
>> int returns a+2^n where n is the length of int in bits.

>> Why is that the best solution, rather than 0, which as far as I
>> understand, limit_cast<unsigned int>(a) would use?

> Both are 32-bit integers. We are casting long to unsigned long.
> And since the original value is a cell position, it is never
> negative.

OK, if it is never negative, then static_cast is safe at this
point. I'm pushing.

Besides, I now see that limit_cast is buggy in converting positive
values from signed to unsigned, returning 0 when it fits!

> it's better than the current (which "casts" 0 to -1 or 0xFFFFFFFF).

As I understand things, this is _bug_ in unary
ulimit_cast. Unary ulimit_cast is described in doxygen comment as:

/** Returns the value, if it fits into ReturnType, otherwise the maximum value of ReturnType. */

I understand we don't want to touch that in stable branch, but anyone
opposing me pushing something like that in master, and similar for
llimit_cast and limit_cast?

// assumptions:
// \forall typename Type:
//     ( (::std::numeric_limits< Type >::min() == 0) XOR ( ::std::numeric_limits< Type >::min() < 0  && ::std::numeric_limits< Type >::is_signed ))
// &&  (::std::numeric_limits< Type >::max() > 0 )

template< typename ReturnType, typename Type >
inline ReturnType ulimit_cast( Type nValue, ReturnType nMax )
{
  if ( ! ::std::numeric_limits< ReturnType >::is_signed && ::std::numeric_limits< Type >::is_signed && nValue < 0 )
    return nMax;
     // Due to implicit type conversion, the comparison in the if occurs in the type
     // that has the biggest ::max()
     // -> safe; compiler gives a warning for mixed signed/unsigned, though
     // Assuming unbounded signed types are unbounded towards both infinities.
  else if ( ! ::std::numeric_limits< ReturnType >::is_bounded ||
            ::std::numeric_limits< ReturnType >::max() >  ::std::numeric_limits< Type >::max() )
    // nValue fits, and it is unsafe to compare nMax to nValue within Type:
    // nMax would be converted
    return static_cast < ReturnType >(nValue);
  else
    // nMax fits in Type; safe to compare to nValue within Type
    return static_cast< ReturnType >(::std::min<Type>(nValue, nMax));
}


Or any C/C++ language lawyer can optimise this into being faster,
while still being safe?

-- 
Lionel


More information about the LibreOffice mailing list