Subzero: Fix g++ warnings.

This tries to use the same -W options that the buildbots use, to reduce the amount of warning spam in the logs.

BUG= none
R=jpp@chromium.org

Review URL: https://codereview.chromium.org/1575873006 .
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index 1d0cf7e..8586016 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -387,6 +387,7 @@
     assert(Mode == OperandARM32Mem::Offset);
     return Reg << kRnShift;
   }
+  llvm_unreachable("(silence g++ warning)");
 }
 
 // Encodes memory address Opnd, and encodes that information into Value, based
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index f23ae0f..ba50afb 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -526,6 +526,7 @@
           }
         }
         assert(Found);
+        (void)Found;
       }
       // Now that a cycle (if any) has been broken, create the actual
       // assignment.
diff --git a/src/IceClFlags.cpp b/src/IceClFlags.cpp
index ed5a71d..6d5b30c 100644
--- a/src/IceClFlags.cpp
+++ b/src/IceClFlags.cpp
@@ -19,10 +19,16 @@
 
 #include "IceClFlagsExtra.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/Support/CommandLine.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 namespace cl = llvm::cl;
 
diff --git a/src/IceClFlagsExtra.h b/src/IceClFlagsExtra.h
index 902aa44..36eac01 100644
--- a/src/IceClFlagsExtra.h
+++ b/src/IceClFlagsExtra.h
@@ -17,11 +17,17 @@
 
 #include "IceDefs.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
 #pragma clang diagnostic ignored "-Wredundant-move"
+#endif // __clang__
+
 #include "llvm/IRReader/IRReader.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 namespace Ice {
 
diff --git a/src/IceCompileServer.cpp b/src/IceCompileServer.cpp
index 1da36b5..2e64f0b 100644
--- a/src/IceCompileServer.cpp
+++ b/src/IceCompileServer.cpp
@@ -19,15 +19,21 @@
 #include "IceELFStreamer.h"
 #include "IceGlobalContext.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_os_ostream.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/StreamingMemoryObject.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 #include <cstdio>
 #include <fstream>
diff --git a/src/IceCompiler.cpp b/src/IceCompiler.cpp
index 447251d..1d6ce37 100644
--- a/src/IceCompiler.cpp
+++ b/src/IceCompiler.cpp
@@ -27,8 +27,11 @@
 #include "IceELFObjectWriter.h"
 #include "PNaClTranslator.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Bitcode/NaCl/NaClReaderWriter.h"
 #include "llvm/IR/LLVMContext.h"
@@ -37,9 +40,11 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/StreamingMemoryObject.h"
 
-#include <regex>
-
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
+
+#include <regex>
 
 namespace Ice {
 
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index e976a8b..0907167 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -26,8 +26,11 @@
 #include "IceTypes.h"
 #include "IceTypeConverter.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -35,7 +38,10 @@
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 // TODO(kschimpf): Remove two namespaces being visible at once.
 using namespace llvm;
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 62a70e4..8a53271 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -26,10 +26,16 @@
 #include "IceTimerTree.h"
 #include "IceTypes.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/Support/Timer.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 #include <algorithm> // max()
 #include <cctype>    // isdigit(), isupper()
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h
index 3a19f47..28e8142 100644
--- a/src/IceGlobalInits.h
+++ b/src/IceGlobalInits.h
@@ -23,13 +23,19 @@
 #include "IceGlobalContext.h"
 #include "IceTypes.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
 #pragma clang diagnostic ignored "-Wredundant-move"
+#endif // __clang__
+
 #include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" // for NaClBitcodeRecord.
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes.
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 #include <memory>
 #include <utility>
diff --git a/src/IceInstARM32.cpp b/src/IceInstARM32.cpp
index 075dd4d..5b9cc14 100644
--- a/src/IceInstARM32.cpp
+++ b/src/IceInstARM32.cpp
@@ -347,7 +347,7 @@
     static_assert(AllowedBits == 0xFFF80000u,
                   "Invalid mask for f32 modified immediates.");
     const float F32 = llvm::cast<ConstantFloat>(C)->getValue();
-    const uint32_t I32 = *reinterpret_cast<const uint32_t *>(&F32);
+    const uint32_t I32 = Utils::bitCopy<uint32_t>(F32);
     if (I32 & ~AllowedBits) {
       // constant has disallowed bits.
       return false;
@@ -376,7 +376,7 @@
     static_assert(AllowedBits == 0xFFFF0000u,
                   "Invalid mask for f64 modified immediates.");
     const double F64 = llvm::cast<ConstantDouble>(C)->getValue();
-    const uint64_t I64 = *reinterpret_cast<const uint64_t *>(&F64);
+    const uint64_t I64 = Utils::bitCopy<uint64_t>(F64);
     if (I64 & 0xFFFFFFFFu) {
       // constant has disallowed bits.
       return false;
@@ -2100,7 +2100,7 @@
   const uint32_t Ret = ((ModifiedImm & a) ? 0x80000000 : 0) |
                        ((ModifiedImm & b) ? 0x3E000000 : 0x40000000) |
                        ((ModifiedImm & cdefgh) << 19);
-  return *reinterpret_cast<const float *>(&Ret);
+  return Utils::bitCopy<float>(Ret);
 }
 
 } // end of anonymous namespace
diff --git a/src/IceTargetLoweringARM32.cpp b/src/IceTargetLoweringARM32.cpp
index 878f95e..08e2607 100644
--- a/src/IceTargetLoweringARM32.cpp
+++ b/src/IceTargetLoweringARM32.cpp
@@ -2623,6 +2623,7 @@
     case AO_Sub:
       return false;
     }
+    llvm_unreachable("(silence g++ warning)");
   }
 
   uint32_t shAmt() const { return ShAmt; }
@@ -3767,11 +3768,11 @@
       _fcmp_hl_NUM
 };
 
-static_assert(_fcmp_hl_NUM == _fcmp_ll_NUM,
+static_assert((uint32_t)_fcmp_hl_NUM == (uint32_t)_fcmp_ll_NUM,
               "Inconsistency between high-level and low-level fcmp tags.");
 #define X(tag, str)                                                            \
   static_assert(                                                               \
-      _fcmp_hl_##tag == _fcmp_ll_##tag,                                        \
+      (uint32_t)_fcmp_hl_##tag == (uint32_t)_fcmp_ll_##tag,                    \
       "Inconsistency between high-level and low-level fcmp tag " #tag);
 ICEINSTFCMP_TABLE
 #undef X
@@ -6302,7 +6303,7 @@
   static uint64_t bitcastToUint64(float Value) {
     static_assert(sizeof(Value) == sizeof(uint32_t),
                   "Float should be 4 bytes.");
-    uint32_t IntValue = *reinterpret_cast<uint32_t *>(&Value);
+    const uint32_t IntValue = Utils::bitCopy<uint32_t>(Value);
     return static_cast<uint64_t>(IntValue);
   }
 };
@@ -6317,7 +6318,7 @@
   static uint64_t bitcastToUint64(double Value) {
     static_assert(sizeof(double) == sizeof(uint64_t),
                   "Double should be 8 bytes.");
-    return *reinterpret_cast<uint64_t *>(&Value);
+    return Utils::bitCopy<uint64_t>(Value);
   }
 };
 const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad";
diff --git a/src/IceTargetLoweringX8632Traits.h b/src/IceTargetLoweringX8632Traits.h
index 00ea2d9..c912160 100644
--- a/src/IceTargetLoweringX8632Traits.h
+++ b/src/IceTargetLoweringX8632Traits.h
@@ -116,7 +116,10 @@
 
     int32_t disp32() const {
       assert(length_ >= 5);
-      return bit_copy<int32_t>(encoding_[length_ - 4]);
+      // TODO(stichnot): This method is not currently used.  Delete it along
+      // with other unused methods, or use a safe version of bitCopy().
+      llvm::report_fatal_error("Unexpected call to disp32()");
+      // return Utils::bitCopy<int32_t>(encoding_[length_ - 4]);
     }
 
     AssemblerFixup *fixup() const { return fixup_; }
diff --git a/src/IceTargetLoweringX8664Traits.h b/src/IceTargetLoweringX8664Traits.h
index bab08a1..87ca3db 100644
--- a/src/IceTargetLoweringX8664Traits.h
+++ b/src/IceTargetLoweringX8664Traits.h
@@ -132,7 +132,10 @@
 
     int32_t disp32() const {
       assert(length_ >= 5);
-      return bit_copy<int32_t>(encoding_[length_ - 4]);
+      // TODO(stichnot): This method is not currently used.  Delete it along
+      // with other unused methods, or use a safe version of bitCopy().
+      llvm::report_fatal_error("Unexpected call to disp32()");
+      // return Utils::bitCopy<int32_t>(encoding_[length_ - 4]);
     }
 
     AssemblerFixup *fixup() const { return fixup_; }
diff --git a/src/IceTimerTree.cpp b/src/IceTimerTree.cpp
index e9b5841..a9baf47 100644
--- a/src/IceTimerTree.cpp
+++ b/src/IceTimerTree.cpp
@@ -17,10 +17,16 @@
 
 #include "IceDefs.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/Support/Timer.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 namespace Ice {
 
diff --git a/src/IceTypeConverter.h b/src/IceTypeConverter.h
index 6b4c028..5983c21 100644
--- a/src/IceTypeConverter.h
+++ b/src/IceTypeConverter.h
@@ -18,11 +18,18 @@
 
 #include "IceDefs.h"
 #include "IceTypes.h"
+
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
 #pragma clang diagnostic ignored "-Wredundant-move"
+#endif // __clang__
+
 #include "llvm/IR/DerivedTypes.h"
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
 
 namespace llvm {
 class LLVMContext;
diff --git a/src/IceUtils.h b/src/IceUtils.h
index 6bdd95e..f9b03bc 100644
--- a/src/IceUtils.h
+++ b/src/IceUtils.h
@@ -19,114 +19,111 @@
 #include <cmath> // std::signbit()
 
 namespace Ice {
+namespace Utils {
 
-/// Similar to bit_cast, but allows copying from types of unrelated sizes. This
-/// method was introduced to enable the strict aliasing optimizations of GCC
-/// 4.4. Basically, GCC mindlessly relies on obscure details in the C++ standard
-/// that make reinterpret_cast virtually useless.
-template <class D, class S> inline D bit_copy(const S &source) {
-  D destination;
+/// Allows copying from types of unrelated sizes. This method was introduced to
+/// enable the strict aliasing optimizations of GCC 4.4. Basically, GCC
+/// mindlessly relies on obscure details in the C++ standard that make
+/// reinterpret_cast virtually useless.
+template <typename D, typename S> inline D bitCopy(const S &Source) {
+  static_assert(sizeof(D) <= sizeof(S),
+                "bitCopy between incompatible type widths");
+  static_assert(!std::is_pointer<S>::value, "");
+  D Destination;
   // This use of memcpy is safe: source and destination cannot overlap.
-  memcpy(&destination, reinterpret_cast<const void *>(&source),
-         sizeof(destination));
-  return destination;
+  memcpy(&Destination, reinterpret_cast<const void *>(&Source), sizeof(D));
+  return Destination;
 }
 
-class Utils {
-  Utils() = delete;
-  Utils(const Utils &) = delete;
-  Utils &operator=(const Utils &) = delete;
+/// Check whether an N-bit two's-complement representation can hold value.
+template <typename T> static inline bool IsInt(int N, T value) {
+  assert((0 < N) &&
+         (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
+  T limit = static_cast<T>(1) << (N - 1);
+  return (-limit <= value) && (value < limit);
+}
 
-public:
-  /// Check whether an N-bit two's-complement representation can hold value.
-  template <typename T> static inline bool IsInt(int N, T value) {
-    assert((0 < N) &&
-           (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
-    T limit = static_cast<T>(1) << (N - 1);
-    return (-limit <= value) && (value < limit);
-  }
+template <typename T> static inline bool IsUint(int N, T value) {
+  assert((0 < N) &&
+         (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
+  T limit = static_cast<T>(1) << N;
+  return (0 <= value) && (value < limit);
+}
 
-  template <typename T> static inline bool IsUint(int N, T value) {
-    assert((0 < N) &&
-           (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(value))));
-    T limit = static_cast<T>(1) << N;
-    return (0 <= value) && (value < limit);
-  }
+/// Check whether the magnitude of value fits in N bits, i.e., whether an
+/// (N+1)-bit sign-magnitude representation can hold value.
+template <typename T> static inline bool IsAbsoluteUint(int N, T Value) {
+  assert((0 < N) &&
+         (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value))));
+  if (Value < 0)
+    Value = -Value;
+  return IsUint(N, Value);
+}
 
-  /// Check whether the magnitude of value fits in N bits, i.e., whether an
-  /// (N+1)-bit sign-magnitude representation can hold value.
-  template <typename T> static inline bool IsAbsoluteUint(int N, T Value) {
-    assert((0 < N) &&
-           (static_cast<unsigned int>(N) < (CHAR_BIT * sizeof(Value))));
-    if (Value < 0)
-      Value = -Value;
-    return IsUint(N, Value);
-  }
+/// Return true if the addition X + Y will cause integer overflow for integers
+/// of type T.
+template <typename T> static inline bool WouldOverflowAdd(T X, T Y) {
+  return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
+          (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
+}
 
-  /// Return true if the addition X + Y will cause integer overflow for integers
-  /// of type T.
-  template <typename T> static inline bool WouldOverflowAdd(T X, T Y) {
-    return ((X > 0 && Y > 0 && (X > std::numeric_limits<T>::max() - Y)) ||
-            (X < 0 && Y < 0 && (X < std::numeric_limits<T>::min() - Y)));
-  }
-
-  /// Adds x to y and stores the result in sum. Returns true if the addition
-  /// overflowed.
-  static inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) {
-    static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type");
+/// Adds x to y and stores the result in sum. Returns true if the addition
+/// overflowed.
+static inline bool add_overflow(uint32_t x, uint32_t y, uint32_t *sum) {
+  static_assert(std::is_same<uint32_t, unsigned>::value, "Must match type");
 #if __has_builtin(__builtin_uadd_overflow)
-    return __builtin_uadd_overflow(x, y, sum);
+  return __builtin_uadd_overflow(x, y, sum);
 #else
-    *sum = x + y;
-    return WouldOverflowAdd(x, y);
+  *sum = x + y;
+  return WouldOverflowAdd(x, y);
 #endif
-  }
+}
 
-  /// Return true if X is already aligned by N, where N is a power of 2.
-  template <typename T> static inline bool IsAligned(T X, intptr_t N) {
-    assert(llvm::isPowerOf2_64(N));
-    return (X & (N - 1)) == 0;
-  }
+/// Return true if X is already aligned by N, where N is a power of 2.
+template <typename T> static inline bool IsAligned(T X, intptr_t N) {
+  assert(llvm::isPowerOf2_64(N));
+  return (X & (N - 1)) == 0;
+}
 
-  /// Return Value adjusted to the next highest multiple of Alignment.
-  static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) {
-    assert(llvm::isPowerOf2_32(Alignment));
-    return (Value + Alignment - 1) & -Alignment;
-  }
+/// Return Value adjusted to the next highest multiple of Alignment.
+static inline uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) {
+  assert(llvm::isPowerOf2_32(Alignment));
+  return (Value + Alignment - 1) & -Alignment;
+}
 
-  /// Return amount which must be added to adjust Pos to the next highest
-  /// multiple of Align.
-  static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) {
-    assert(llvm::isPowerOf2_64(Align));
-    uint64_t Mod = Pos & (Align - 1);
-    if (Mod == 0)
-      return 0;
-    return Align - Mod;
-  }
+/// Return amount which must be added to adjust Pos to the next highest
+/// multiple of Align.
+static inline uint64_t OffsetToAlignment(uint64_t Pos, uint64_t Align) {
+  assert(llvm::isPowerOf2_64(Align));
+  uint64_t Mod = Pos & (Align - 1);
+  if (Mod == 0)
+    return 0;
+  return Align - Mod;
+}
 
-  /// Rotate the value bit pattern to the left by shift bits.
-  /// Precondition: 0 <= shift < 32
-  static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) {
-    if (shift == 0)
-      return value;
-    return (value << shift) | (value >> (32 - shift));
-  }
+/// Rotate the value bit pattern to the left by shift bits.
+/// Precondition: 0 <= shift < 32
+static inline uint32_t rotateLeft32(uint32_t value, uint32_t shift) {
+  if (shift == 0)
+    return value;
+  return (value << shift) | (value >> (32 - shift));
+}
 
-  /// Rotate the value bit pattern to the right by shift bits.
-  static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) {
-    if (shift == 0)
-      return value;
-    return (value >> shift) | (value << (32 - shift));
-  }
+/// Rotate the value bit pattern to the right by shift bits.
+static inline uint32_t rotateRight32(uint32_t value, uint32_t shift) {
+  if (shift == 0)
+    return value;
+  return (value >> shift) | (value << (32 - shift));
+}
 
-  /// Returns true if Val is +0.0. It requires T to be a floating point type.
-  template <typename T> static bool isPositiveZero(T Val) {
-    static_assert(std::is_floating_point<T>::value,
-                  "Input type must be floating point");
-    return Val == 0 && !std::signbit(Val);
-  }
-};
+/// Returns true if Val is +0.0. It requires T to be a floating point type.
+template <typename T> static bool isPositiveZero(T Val) {
+  static_assert(std::is_floating_point<T>::value,
+                "Input type must be floating point");
+  return Val == 0 && !std::signbit(Val);
+}
 
+} // end of namespace Utils
 } // end of namespace Ice
 
 #endif // SUBZERO_SRC_ICEUTILS_H
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index ddf6342..a7b367c 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -23,8 +23,11 @@
 #include "IceInst.h"
 #include "IceOperand.h"
 
+#ifdef __clang__
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-parameter"
+#endif // __clang__
+
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h"
@@ -35,8 +38,12 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-#include <unordered_set>
+
+#ifdef __clang__
 #pragma clang diagnostic pop
+#endif // __clang__
+
+#include <unordered_set>
 
 // Define a hash function for SmallString's, so that it can be used in hash
 // tables.
@@ -190,7 +197,7 @@
                   "IntType and FpType should be the same width");
     assert(BitWidth == sizeof(IntType) * CHAR_BIT);
     auto V = static_cast<IntType>(Val);
-    return reinterpret_cast<FpType &>(V);
+    return Ice::Utils::bitCopy<FpType>(V);
   }
 
 private: