[vm] Fix ia32/x64 gcc build.

(The simulators are broken at runtime.)

Change-Id: I10089cad44fca57145cfdd598342279f07c6d7fd
Reviewed-on: https://dart-review.googlesource.com/75205
Reviewed-by: RĂ©gis Crelier <regis@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index e29aa03..4e9d66b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -690,11 +690,13 @@
       # See http://lwn.net/Articles/192624/ .
       "-Wl,-O1",
       "-Wl,--gc-sections",
+    ]
 
+    if (is_clang) {
       # Identical code folding to reduce size.
       # Warning: This changes C/C++ semantics of function pointer comparison.
-      "-Wl,--icf=all",
-    ]
+      common_optimize_on_ldflags += [ "-Wl,--icf=all" ]
+    }
 
     if (!using_sanitizer) {
       # Functions interposed by the sanitizers can make ld think
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index bc08e00..865e716 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -158,6 +158,7 @@
       "-Wvla",
       "-Wno-conversion-null",
       "-Woverloaded-virtual",
+      "-Wno-comments",  # Conflicts with clang-format.
       "-g3",
       "-ggdb3",
       "-fno-rtti",
diff --git a/runtime/bin/options.h b/runtime/bin/options.h
index e4edbcf..336d934 100644
--- a/runtime/bin/options.h
+++ b/runtime/bin/options.h
@@ -119,7 +119,25 @@
   static OptionProcessor_##name option_##name;
 
 #define DEFINE_BOOL_OPTION(name, variable)                                     \
-  DEFINE_BOOL_OPTION_CB(name, { variable = true; })
+  class OptionProcessor_##name : public OptionProcessor {                      \
+   public:                                                                     \
+    virtual bool Process(const char* option, CommandLineOptions* vm_options) { \
+      const char* value = OptionProcessor::ProcessOption(option, "--" #name);  \
+      if (value == NULL) {                                                     \
+        return false;                                                          \
+      }                                                                        \
+      if (*value == '=') {                                                     \
+        Log::PrintErr("Non-empty value for option " #name "\n");               \
+        return false;                                                          \
+      }                                                                        \
+      if (*value != '\0') {                                                    \
+        return false;                                                          \
+      }                                                                        \
+      variable = true;                                                         \
+      return true;                                                             \
+    }                                                                          \
+  };                                                                           \
+  static OptionProcessor_##name option_##name;
 
 #define DEFINE_BOOL_OPTION_SHORT(short_name, long_name, variable)              \
   class OptionProcessor_##long_name : public OptionProcessor {                 \
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 61b4766..41fcd15 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1141,7 +1141,6 @@
       (representation() == kUnboxedFloat64x2)) {
     const VRegister result = locs()->out(0).fpu_reg();
     switch (class_id()) {
-      ASSERT(aligned());
       case kTypedDataFloat32ArrayCid:
         // Load single precision float.
         if (aligned()) {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 4392efd..e8b948c 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1190,6 +1190,7 @@
       first_parameter_offset = ReaderOffset() + data_program_offset_;
     }
   }
+  USE(first_parameter_offset);
   // Current position: About to read list of positionals.
 
   // Should never build a dynamic invocation forwarder for equality
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 5248782..45d836a 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -283,6 +283,9 @@
         case CatchEntryMove::SourceKind::kUint32Slot:
           value = Integer::New(*SlotAt<uint32_t>(fp, move.src_slot()));
           break;
+
+        default:
+          UNREACHABLE();
       }
 
       *TaggedSlotAt(fp, move.dest_slot()) = value;
@@ -296,7 +299,7 @@
     NoSafepointScope no_safepoint;
     ReadStream stream(static_cast<uint8_t*>(td.DataAddr(0)), td.Length());
 
-    intptr_t prefix_length, suffix_length, suffix_offset;
+    intptr_t prefix_length = 0, suffix_length = 0, suffix_offset = 0;
     while (stream.PendingBytes() > 0) {
       intptr_t target_pc_offset = Reader::Read(&stream);
       prefix_length = Reader::Read(&stream);
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 62a2fd5..9650957 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -890,7 +890,7 @@
   UNIMPLEMENTED();
 #endif
   ASSERT(Function::HasCode(function));
-  RawCode* code = function->ptr()->code_;
+  RawCode* volatile code = function->ptr()->code_;
   ASSERT(code != StubCode::LazyCompile_entry()->code());
   // TODO(regis): Once we share the same stack, try to invoke directly.
 #if defined(DEBUG)
@@ -902,9 +902,9 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   typedef RawObject* (*invokestub)(RawCode * code, RawArray * argdesc,
                                    RawObject * *arg0, Thread * thread);
-  invokestub entrypoint = reinterpret_cast<invokestub>(
+  invokestub volatile entrypoint = reinterpret_cast<invokestub>(
       StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint());
-  RawObject* result;
+  RawObject* volatile result;
   Exit(thread, *FP, call_top + 1, *pc);
   {
     InterpreterSetjmpBuffer buffer(this);
@@ -969,11 +969,13 @@
       RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
       intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
       RawAbstractType* field_type = field->ptr()->type_;
-      const classid_t cid =
-          field_type->GetClassId() == kTypeCid
-              ? Smi::Value(reinterpret_cast<RawSmi*>(
-                    Type::RawCast(field_type)->ptr()->type_class_id_))
-              : kIllegalCid;  // Not really illegal, but not a Type to skip.
+      classid_t cid;
+      if (field_type->GetClassId() == kTypeCid) {
+        cid = Smi::Value(reinterpret_cast<RawSmi*>(
+            Type::RawCast(field_type)->ptr()->type_class_id_));
+      } else {
+        cid = kIllegalCid;  // Not really illegal, but not a Type to skip.
+      }
       // Perform type test of value if field type is not one of dynamic, object,
       // or void, and if the value is not null.
       RawObject* null_value = Object::null();
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 8951295..db660f8 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -1592,8 +1592,8 @@
             // Registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
             // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd");
             rd_val = get_register(rd);
-            // fall through
           }
+          /* Falls through */
           case 0: {
             // Registers rd, rn, rm are encoded as rn, rm, rs.
             // Format(instr, "mul'cond's 'rn, 'rm, 'rs");
@@ -1650,6 +1650,7 @@
               // umaal is only in ARMv6 and above.
               UnimplementedInstruction(instr);
             }
+            /* Falls through */
           case 5:
           // Registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
           // Format(instr, "umlal'cond's 'rd, 'rn, 'rm, 'rs");