This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix compile errors about shift counts too large.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b7a4e9d8e6a854d2344ab7963e531d6f19571d2e

commit b7a4e9d8e6a854d2344ab7963e531d6f19571d2e
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Sat Feb 6 18:18:51 2016 -0800

    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.

Diff:
---
 gold/ChangeLog | 11 +++++++++++
 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;
   }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]