diff options
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/reloc.h | 40 |
2 files changed, 41 insertions, 10 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 628547e..e114198 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,16 @@ 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 * reloc.h (Relocate_functions::Overflow_check): Add comments. * x86_64.cc (X86_64_relocate_functions): New class. diff --git a/gold/reloc.h b/gold/reloc.h index 72f6c46..0730a45 100644 --- a/gold/reloc.h +++ b/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; } |