Fix compile errors about shift counts too large.
In order to get around the optimizer and newer compiler warnings about shift counts, the overflow checking code had resorted to some messy shifting, and with the never-before-seen instantiations of the template functions, we were still running afoul of the compiler checks. This patch replaces those messy shift sequences with a simple class template that provides the min and max limits for any bit size up to 64, with a specialization for 64 that prevents the compiler from complaining. gold/ PR gold/19577 * reloc.h (Limits): New class. (Bits::has_overflow32): Use min/max values from Limits. (Bits::has_unsigned_overflow32): Likewise. (Bits::has_signed_unsigned_overflow32): Likewise. (Bits::has_overflow): Likewise. (Bits::has_unsigned_overflow): Likewise. (Bits::has_signed_unsigned_overflow64): Likewise.
This commit is contained in:
parent
6c043259a3
commit
b7a4e9d8e6
2 changed files with 41 additions and 10 deletions
|
@ -1,3 +1,14 @@
|
|||
2016-02-06 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/19577
|
||||
* reloc.h (Limits): New class.
|
||||
(Bits::has_overflow32): Use min/max values from Limits.
|
||||
(Bits::has_unsigned_overflow32): Likewise.
|
||||
(Bits::has_signed_unsigned_overflow32): Likewise.
|
||||
(Bits::has_overflow): Likewise.
|
||||
(Bits::has_unsigned_overflow): Likewise.
|
||||
(Bits::has_signed_unsigned_overflow64): Likewise.
|
||||
|
||||
2016-02-06 Cary Coutant <ccoutant@gmail.com>
|
||||
|
||||
PR gold/19567
|
||||
|
|
40
gold/reloc.h
40
gold/reloc.h
|
@ -974,6 +974,26 @@ class Relocate_functions
|
|||
CHECK_NONE); }
|
||||
};
|
||||
|
||||
// Convenience class for min and max values of a given BITS length.
|
||||
|
||||
template<int bits>
|
||||
class Limits
|
||||
{
|
||||
public:
|
||||
static const uint64_t MAX_UNSIGNED = (1ULL << bits) - 1;
|
||||
static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1;
|
||||
static const int64_t MIN_SIGNED = -MAX_SIGNED - 1;
|
||||
};
|
||||
|
||||
template<>
|
||||
class Limits<64>
|
||||
{
|
||||
public:
|
||||
static const uint64_t MAX_UNSIGNED = ~0ULL;
|
||||
static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1;
|
||||
static const int64_t MIN_SIGNED = -MAX_SIGNED - 1;
|
||||
};
|
||||
|
||||
// Integer manipulation functions used by various targets when
|
||||
// performing relocations.
|
||||
|
||||
|
@ -1006,8 +1026,8 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 32);
|
||||
if (bits == 32)
|
||||
return false;
|
||||
int32_t max = (1 << (bits - 1)) - 1;
|
||||
int32_t min = -(1 << (bits - 1));
|
||||
const int32_t max = static_cast<int32_t>(Limits<bits>::MAX_SIGNED);
|
||||
const int32_t min = static_cast<int32_t>(Limits<bits>::MIN_SIGNED);
|
||||
int32_t as_signed = static_cast<int32_t>(val);
|
||||
return as_signed > max || as_signed < min;
|
||||
}
|
||||
|
@ -1020,7 +1040,7 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 32);
|
||||
if (bits == 32)
|
||||
return false;
|
||||
uint32_t max = static_cast<uint32_t>((1U << bits) - 1);
|
||||
const uint32_t max = static_cast<uint32_t>(Limits<bits>::MAX_UNSIGNED);
|
||||
return val > max;
|
||||
}
|
||||
|
||||
|
@ -1034,8 +1054,8 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 32);
|
||||
if (bits == 32)
|
||||
return false;
|
||||
int32_t max = static_cast<int32_t>((1U << bits) - 1);
|
||||
int32_t min = -(1 << (bits - 1));
|
||||
const int32_t max = static_cast<int32_t>(Limits<bits>::MAX_UNSIGNED);
|
||||
const int32_t min = static_cast<int32_t>(Limits<bits>::MIN_SIGNED);
|
||||
int32_t as_signed = static_cast<int32_t>(val);
|
||||
return as_signed > max || as_signed < min;
|
||||
}
|
||||
|
@ -1072,8 +1092,8 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 64);
|
||||
if (bits == 64)
|
||||
return false;
|
||||
int64_t max = (static_cast<int64_t>(1) << (bits - 1)) - 1;
|
||||
int64_t min = -(static_cast<int64_t>(1) << (bits - 1));
|
||||
const int64_t max = Limits<bits>::MAX_SIGNED;
|
||||
const int64_t min = Limits<bits>::MIN_SIGNED;
|
||||
int64_t as_signed = static_cast<int64_t>(val);
|
||||
return as_signed > max || as_signed < min;
|
||||
}
|
||||
|
@ -1086,7 +1106,7 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 64);
|
||||
if (bits == 64)
|
||||
return false;
|
||||
uint64_t max = (static_cast<uint64_t>(1) << bits) - 1;
|
||||
const uint64_t max = Limits<bits>::MAX_UNSIGNED;
|
||||
return val > max;
|
||||
}
|
||||
|
||||
|
@ -1100,8 +1120,8 @@ class Bits
|
|||
gold_assert(bits > 0 && bits <= 64);
|
||||
if (bits == 64)
|
||||
return false;
|
||||
int64_t max = static_cast<int64_t>((static_cast<uint64_t>(1) << bits) - 1);
|
||||
int64_t min = -(static_cast<int64_t>(1) << (bits - 1));
|
||||
const int64_t max = static_cast<int64_t>(Limits<bits>::MAX_UNSIGNED);
|
||||
const int64_t min = Limits<bits>::MIN_SIGNED;
|
||||
int64_t as_signed = static_cast<int64_t>(val);
|
||||
return as_signed > max || as_signed < min;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue