ART: Introduce NO_RETURN, Mark DoLongJump noreturn

Add NO_RETURN macro that adds C++11 noreturn attribute. Mark
DoLongJump methods as noreturn.

Change-Id: Ifde4318e370493237050d4c1349285a0382df23f
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index e607e15..0b1f14d 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -36,6 +36,7 @@
 #include "arch/instruction_set_features.h"
 #include "arch/mips/instruction_set_features_mips.h"
 #include "base/dumpable.h"
+#include "base/macros.h"
 #include "base/stl_util.h"
 #include "base/stringpiece.h"
 #include "base/timing_logger.h"
@@ -97,7 +98,7 @@
   va_end(ap);
 }
 
-[[noreturn]] static void Usage(const char* fmt, ...) {
+NO_RETURN static void Usage(const char* fmt, ...) {
   va_list ap;
   va_start(ap, fmt);
   UsageErrorV(fmt, ap);
@@ -326,7 +327,7 @@
             message.c_str());
   }
 
-  [[noreturn]] static void Fatal(const std::string& message) {
+  NO_RETURN static void Fatal(const std::string& message) {
     Message('F', message);
     exit(1);
   }
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 2059a96..3c6a23d 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -763,7 +763,7 @@
   va_end(ap);
 }
 
-[[noreturn]] static void Usage(const char *fmt, ...) {
+NO_RETURN static void Usage(const char *fmt, ...) {
   va_list ap;
   va_start(ap, fmt);
   UsageErrorV(fmt, ap);
diff --git a/runtime/arch/arm/context_arm.cc b/runtime/arch/arm/context_arm.cc
index c181e43..5bd23d0 100644
--- a/runtime/arch/arm/context_arm.cc
+++ b/runtime/arch/arm/context_arm.cc
@@ -106,7 +106,7 @@
   fprs_[S15] = nullptr;
 }
 
-extern "C" void art_quick_do_long_jump(uint32_t*, uint32_t*);
+extern "C" NO_RETURN void art_quick_do_long_jump(uint32_t*, uint32_t*);
 
 void ArmContext::DoLongJump() {
   uintptr_t gprs[kNumberOfCoreRegisters];
diff --git a/runtime/arch/arm/context_arm.h b/runtime/arch/arm/context_arm.h
index 1ca973e..5bdeda7 100644
--- a/runtime/arch/arm/context_arm.h
+++ b/runtime/arch/arm/context_arm.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_arm.h"
 
 namespace art {
@@ -76,7 +77,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pointers to register locations, initialized to NULL or the specific registers below.
diff --git a/runtime/arch/arm64/context_arm64.cc b/runtime/arch/arm64/context_arm64.cc
index 7fc0555..ec9c122 100644
--- a/runtime/arch/arm64/context_arm64.cc
+++ b/runtime/arch/arm64/context_arm64.cc
@@ -133,7 +133,7 @@
   fprs_[D31] = nullptr;
 }
 
-extern "C" void art_quick_do_long_jump(uint64_t*, uint64_t*);
+extern "C" NO_RETURN void art_quick_do_long_jump(uint64_t*, uint64_t*);
 
 void Arm64Context::DoLongJump() {
   uint64_t gprs[kNumberOfXRegisters];
diff --git a/runtime/arch/arm64/context_arm64.h b/runtime/arch/arm64/context_arm64.h
index 6a4485b..f486779 100644
--- a/runtime/arch/arm64/context_arm64.h
+++ b/runtime/arch/arm64/context_arm64.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_arm64.h"
 
 namespace art {
@@ -76,7 +77,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pointers to register locations, initialized to NULL or the specific registers below.
diff --git a/runtime/arch/context.h b/runtime/arch/context.h
index ed8cab0..f86f9ae 100644
--- a/runtime/arch/context.h
+++ b/runtime/arch/context.h
@@ -20,6 +20,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include "base/macros.h"
 #include "base/mutex.h"
 
 namespace art {
@@ -78,7 +79,7 @@
   virtual void SmashCallerSaves() = 0;
 
   // Switches execution of the executing context to this context
-  virtual void DoLongJump() = 0;
+  NO_RETURN virtual void DoLongJump() = 0;
 
  protected:
   enum {
diff --git a/runtime/arch/mips/context_mips.cc b/runtime/arch/mips/context_mips.cc
index 6c0ab98..3b525be 100644
--- a/runtime/arch/mips/context_mips.cc
+++ b/runtime/arch/mips/context_mips.cc
@@ -90,7 +90,7 @@
   gprs_[A3] = nullptr;
 }
 
-extern "C" void art_quick_do_long_jump(uint32_t*, uint32_t*);
+extern "C" NO_RETURN void art_quick_do_long_jump(uint32_t*, uint32_t*);
 
 void MipsContext::DoLongJump() {
   uintptr_t gprs[kNumberOfCoreRegisters];
diff --git a/runtime/arch/mips/context_mips.h b/runtime/arch/mips/context_mips.h
index d8a0b67..cbad3f963 100644
--- a/runtime/arch/mips/context_mips.h
+++ b/runtime/arch/mips/context_mips.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_mips.h"
 
 namespace art {
@@ -75,7 +76,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pointers to registers in the stack, initialized to NULL except for the special cases below.
diff --git a/runtime/arch/mips64/context_mips64.cc b/runtime/arch/mips64/context_mips64.cc
index 1c96bd4..ce99b40 100644
--- a/runtime/arch/mips64/context_mips64.cc
+++ b/runtime/arch/mips64/context_mips64.cc
@@ -121,7 +121,7 @@
   fprs_[F23] = nullptr;
 }
 
-extern "C" void art_quick_do_long_jump(uintptr_t*, uintptr_t*);
+extern "C" NO_RETURN void art_quick_do_long_jump(uintptr_t*, uintptr_t*);
 
 void Mips64Context::DoLongJump() {
   uintptr_t gprs[kNumberOfGpuRegisters];
diff --git a/runtime/arch/mips64/context_mips64.h b/runtime/arch/mips64/context_mips64.h
index 1046723..2cc2b8d 100644
--- a/runtime/arch/mips64/context_mips64.h
+++ b/runtime/arch/mips64/context_mips64.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_mips64.h"
 
 namespace art {
@@ -75,7 +76,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pointers to registers in the stack, initialized to NULL except for the special cases below.
diff --git a/runtime/arch/x86/context_x86.cc b/runtime/arch/x86/context_x86.cc
index 4ea4684..52a35dd 100644
--- a/runtime/arch/x86/context_x86.cc
+++ b/runtime/arch/x86/context_x86.cc
@@ -133,6 +133,7 @@
 #else
   UNIMPLEMENTED(FATAL);
 #endif
+  UNREACHABLE();
 }
 
 }  // namespace x86
diff --git a/runtime/arch/x86/context_x86.h b/runtime/arch/x86/context_x86.h
index c66a9dc..ace4670 100644
--- a/runtime/arch/x86/context_x86.h
+++ b/runtime/arch/x86/context_x86.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_x86.h"
 
 namespace art {
@@ -75,7 +76,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pretend XMM registers are made of uin32_t pieces, because they are manipulated
diff --git a/runtime/arch/x86_64/context_x86_64.cc b/runtime/arch/x86_64/context_x86_64.cc
index cdc2ec7..6336541 100644
--- a/runtime/arch/x86_64/context_x86_64.cc
+++ b/runtime/arch/x86_64/context_x86_64.cc
@@ -105,7 +105,7 @@
   *fprs_[reg] = value;
 }
 
-extern "C" void art_quick_do_long_jump(uintptr_t*, uintptr_t*);
+extern "C" NO_RETURN void art_quick_do_long_jump(uintptr_t*, uintptr_t*);
 
 void X86_64Context::DoLongJump() {
 #if defined(__x86_64__)
@@ -127,6 +127,7 @@
   art_quick_do_long_jump(gprs, fprs);
 #else
   UNIMPLEMENTED(FATAL);
+  UNREACHABLE();
 #endif
 }
 
diff --git a/runtime/arch/x86_64/context_x86_64.h b/runtime/arch/x86_64/context_x86_64.h
index 0dda06e..d03aa45 100644
--- a/runtime/arch/x86_64/context_x86_64.h
+++ b/runtime/arch/x86_64/context_x86_64.h
@@ -19,6 +19,7 @@
 
 #include "arch/context.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "registers_x86_64.h"
 
 namespace art {
@@ -75,7 +76,7 @@
   void SetFPR(uint32_t reg, uintptr_t value) OVERRIDE;
 
   void SmashCallerSaves() OVERRIDE;
-  void DoLongJump() OVERRIDE;
+  NO_RETURN void DoLongJump() OVERRIDE;
 
  private:
   // Pointers to register locations. Values are initialized to NULL or the special registers below.
diff --git a/runtime/base/macros.h b/runtime/base/macros.h
index f705469..3a9de5f 100644
--- a/runtime/base/macros.h
+++ b/runtime/base/macros.h
@@ -186,6 +186,9 @@
 // without the UNREACHABLE a return statement would be necessary.
 #define UNREACHABLE  __builtin_unreachable
 
+// Add the C++11 noreturn attribute.
+#define NO_RETURN [[ noreturn ]]  // NOLINT[whitespace/braces] [5]
+
 // The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
 // between switch labels:
 //  switch (x) {
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index ce7c1c3..06b809f 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -25,6 +25,7 @@
 #include <sstream>
 
 #include "base/logging.h"
+#include "base/macros.h"
 #include "class_linker-inl.h"
 #include "common_throws.h"
 #include "dex_file-inl.h"
@@ -349,8 +350,8 @@
     uint32_t dex_pc, const instrumentation::Instrumentation* instrumentation)
         SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame)
-  __attribute__((cold, noreturn))
+NO_RETURN void UnexpectedOpcode(const Instruction* inst, const ShadowFrame& shadow_frame)
+  __attribute__((cold))
   SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruction* inst,
diff --git a/runtime/native/java_lang_Runtime.cc b/runtime/native/java_lang_Runtime.cc
index 97b17bf..84b18ab 100644
--- a/runtime/native/java_lang_Runtime.cc
+++ b/runtime/native/java_lang_Runtime.cc
@@ -20,6 +20,7 @@
 #include <limits.h>
 #include <unistd.h>
 
+#include "base/macros.h"
 #include "gc/heap.h"
 #include "handle_scope-inl.h"
 #include "jni_internal.h"
@@ -39,7 +40,7 @@
   Runtime::Current()->GetHeap()->CollectGarbage(false);
 }
 
-[[noreturn]] static void Runtime_nativeExit(JNIEnv*, jclass, jint status) {
+NO_RETURN static void Runtime_nativeExit(JNIEnv*, jclass, jint status) {
   LOG(INFO) << "System.exit called, status: " << status;
   Runtime::Current()->CallExitHook(status);
   exit(status);
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 85ec803..7bdf652 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -353,6 +353,7 @@
   context_->SetPC(handler_quick_frame_pc_);
   context_->SmashCallerSaves();
   context_->DoLongJump();
+  UNREACHABLE();
 }
 
 }  // namespace art
diff --git a/runtime/quick_exception_handler.h b/runtime/quick_exception_handler.h
index 31622de..162b1dc 100644
--- a/runtime/quick_exception_handler.h
+++ b/runtime/quick_exception_handler.h
@@ -18,6 +18,7 @@
 #define ART_RUNTIME_QUICK_EXCEPTION_HANDLER_H_
 
 #include "base/logging.h"
+#include "base/macros.h"
 #include "base/mutex.h"
 #include "stack.h"  // StackReference
 
@@ -48,7 +49,7 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void DeoptimizeStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void UpdateInstrumentationStack() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  NO_RETURN void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void SetHandlerQuickFrame(StackReference<mirror::ArtMethod>* handler_quick_frame) {
     handler_quick_frame_ = handler_quick_frame;
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 118c838..e6304bd 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -28,6 +28,7 @@
 
 #include "arch/instruction_set.h"
 #include "base/allocator.h"
+#include "base/macros.h"
 #include "compiler_callbacks.h"
 #include "gc_root.h"
 #include "instrumentation.h"
@@ -185,7 +186,7 @@
 
   // Aborts semi-cleanly. Used in the implementation of LOG(FATAL), which most
   // callers should prefer.
-  [[noreturn]] static void Abort() LOCKS_EXCLUDED(Locks::abort_lock_);
+  NO_RETURN static void Abort() LOCKS_EXCLUDED(Locks::abort_lock_);
 
   // Returns the "main" ThreadGroup, used when attaching user threads.
   jobject GetMainThreadGroup() const;
diff --git a/runtime/thread.cc b/runtime/thread.cc
index cb6ed64..3b48f49 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2044,8 +2044,6 @@
   }
   exception_handler.UpdateInstrumentationStack();
   exception_handler.DoLongJump();
-  LOG(FATAL) << "UNREACHABLE";
-  UNREACHABLE();
 }
 
 Context* Thread::GetLongJumpContext() {
diff --git a/runtime/thread.h b/runtime/thread.h
index 26b7b6f..83cedbb 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -353,7 +353,7 @@
   }
 
   // Find catch block and perform long jump to appropriate exception handle
-  void QuickDeliverException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  NO_RETURN void QuickDeliverException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   Context* GetLongJumpContext();
   void ReleaseLongJumpContext(Context* context) {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 05a0bff..d0f014a 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -228,8 +228,7 @@
 
 #if HAVE_TIMED_RWLOCK
 // Attempt to rectify locks so that we dump thread list with required locks before exiting.
-static void UnsafeLogFatalForThreadSuspendAllTimeout() __attribute__((noreturn));
-static void UnsafeLogFatalForThreadSuspendAllTimeout() {
+NO_RETURN static void UnsafeLogFatalForThreadSuspendAllTimeout() {
   Runtime* runtime = Runtime::Current();
   std::ostringstream ss;
   ss << "Thread suspend timeout\n";