• Sergei Golubchik's avatar
    MDEV-7973 bigint fail with gcc 5.0 · ae18a285
    Sergei Golubchik authored
    -LONGLONG_MIN is the undefined behavior in C.
    longlong2decimal() used to do this:
    
      int longlong2decimal(longlong from, decimal_t *to) {
        if ((to->sign= from < 0))
          return ull2dec(-from, to);
        return ull2dec(from, to);
    
    and later in ull2dec() (DIG_BASE is 1000000000):
    
      static int ull2dec(ulonglong from, decimal_t *to) {
        for (intg1=1; from >= DIG_BASE; intg1++, from/=DIG_BASE) {}
    
    this breaks in gcc-5 at -O3. Here ull2dec is inlined into
    longlong2decimal. And gcc-5 believes that 'from' in the
    inlined ull2dec is always a positive integer (indeed, if it was
    negative, then -from was used instead). So gcc-5 uses
    *signed* comparison with DIG_BASE.
    
    Fix: make a special case for LONGLONG_MIN, don't negate it
    ae18a285
decimal.c 86.6 KB