From 084d7d6b014443be7625fb9d8f1ddd309a22f6f4 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 17:02:29 -0400
Subject: [PATCH 1/9] common: Change semantics of UNREACHABLE to
 unconditionally crash

---
 src/audio_core/command_generator.cpp          |  4 +-
 src/audio_core/effect_context.cpp             |  4 +-
 src/audio_core/splitter_context.cpp           |  2 +-
 src/audio_core/voice_context.cpp              |  4 +-
 src/common/assert.cpp                         |  5 +++
 src/common/assert.h                           | 14 ++++++-
 src/common/settings.cpp                       |  2 +-
 src/core/crypto/key_manager.cpp               |  2 -
 src/core/file_sys/nca_patch.cpp               |  2 +-
 src/core/file_sys/registered_cache.cpp        |  2 +-
 src/core/file_sys/vfs_real.cpp                |  2 +-
 src/core/frontend/applets/controller.cpp      |  2 +-
 src/core/hid/hid_core.cpp                     |  4 +-
 src/core/hle/kernel/hle_ipc.h                 |  2 +-
 src/core/hle/kernel/init/init_slab_setup.cpp  |  2 +-
 src/core/hle/kernel/k_address_arbiter.h       |  4 +-
 src/core/hle/kernel/k_address_space_info.cpp  |  4 +-
 src/core/hle/kernel/k_memory_manager.cpp      |  2 +-
 src/core/hle/kernel/k_page_table.cpp          | 16 +++-----
 src/core/hle/kernel/k_port.cpp                |  2 +-
 src/core/hle/kernel/k_process.cpp             |  2 +-
 src/core/hle/kernel/k_server_session.cpp      |  4 +-
 src/core/hle/kernel/k_thread.cpp              |  2 +-
 src/core/hle/kernel/svc.cpp                   |  2 +-
 .../service/am/applets/applet_controller.cpp  |  2 +-
 .../hle/service/am/applets/applet_error.cpp   |  2 +-
 .../am/applets/applet_general_backend.cpp     |  4 +-
 .../service/am/applets/applet_mii_edit.cpp    |  2 +-
 .../am/applets/applet_profile_select.cpp      |  2 +-
 .../am/applets/applet_software_keyboard.cpp   |  2 +-
 .../service/am/applets/applet_web_browser.cpp |  4 +-
 src/core/hle/service/filesystem/fsp_srv.cpp   |  2 +-
 src/core/hle/service/hid/controllers/npad.cpp |  8 ++--
 src/core/hle/service/hid/hid.cpp              |  2 +-
 src/core/hle/service/ldr/ldr.cpp              |  2 +-
 src/core/hle/service/mii/mii_manager.cpp      |  2 +-
 .../hle/service/nvdrv/syncpoint_manager.cpp   |  2 +-
 .../nvflinger/buffer_queue_producer.cpp       |  2 +-
 .../time/standard_user_system_clock_core.cpp  |  4 +-
 src/core/hle/service/time/time_manager.cpp    | 10 ++---
 .../hle/service/time/time_zone_manager.cpp    |  2 +-
 src/core/tools/freezer.cpp                    |  1 -
 .../command_classes/codecs/codec.cpp          |  2 +-
 src/video_core/command_classes/vic.cpp        |  2 +-
 src/video_core/engines/maxwell_3d.h           | 12 +++---
 src/video_core/engines/maxwell_dma.cpp        |  4 +-
 src/video_core/gpu_thread.cpp                 |  2 +-
 src/video_core/macro/macro.cpp                |  2 +-
 src/video_core/macro/macro_interpreter.cpp    |  1 -
 src/video_core/memory_manager.cpp             |  6 +--
 .../renderer_opengl/gl_graphics_pipeline.cpp  |  4 +-
 .../renderer_opengl/gl_shader_cache.cpp       |  4 +-
 .../renderer_opengl/gl_texture_cache.cpp      | 38 +++++++++----------
 .../renderer_opengl/maxwell_to_gl.h           | 12 +++---
 .../renderer_opengl/renderer_opengl.cpp       |  4 +-
 .../renderer_opengl/util_shaders.cpp          |  2 +-
 .../renderer_vulkan/maxwell_to_vk.cpp         | 12 +++---
 .../renderer_vulkan/vk_buffer_cache.cpp       |  4 +-
 .../renderer_vulkan/vk_compute_pass.cpp       |  2 +-
 .../renderer_vulkan/vk_pipeline_cache.cpp     |  4 +-
 .../vk_staging_buffer_pool.cpp                |  2 +-
 .../renderer_vulkan/vk_texture_cache.cpp      | 24 ++++++------
 src/video_core/shader_environment.cpp         |  2 +-
 src/video_core/surface.cpp                    |  6 +--
 src/video_core/texture_cache/image_info.cpp   |  2 +-
 .../texture_cache/image_view_info.cpp         |  2 +-
 src/video_core/texture_cache/samples_helper.h |  4 +-
 src/video_core/texture_cache/texture_cache.h  | 20 +++++-----
 src/video_core/textures/decoders.cpp          |  8 ++--
 .../vulkan_common/vulkan_device.cpp           | 14 ++++---
 .../vulkan_common/vulkan_memory_allocator.cpp |  6 +--
 src/yuzu/applets/qt_controller.cpp            |  2 +-
 72 files changed, 182 insertions(+), 173 deletions(-)

diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index ff20ed00f..f97520820 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -429,7 +429,7 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
                                   in_params.node_id);
             break;
         default:
-            UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format);
+            ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format);
         }
     }
 }
@@ -1312,7 +1312,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, std::s
                                 samples_to_read - samples_read, channel, temp_mix_offset);
                 break;
             default:
-                UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format);
+                ASSERT_MSG(false, "Unimplemented sample format={}", in_params.sample_format);
             }
 
             temp_mix_offset += samples_decoded;
diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp
index 51059580e..79bcd1192 100644
--- a/src/audio_core/effect_context.cpp
+++ b/src/audio_core/effect_context.cpp
@@ -50,7 +50,7 @@ EffectBase* EffectContext::RetargetEffect(std::size_t i, EffectType effect) {
         effects[i] = std::make_unique<EffectBiquadFilter>();
         break;
     default:
-        UNREACHABLE_MSG("Unimplemented effect {}", effect);
+        ASSERT_MSG(false, "Unimplemented effect {}", effect);
         effects[i] = std::make_unique<EffectStubbed>();
     }
     return GetInfo(i);
@@ -104,7 +104,7 @@ void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) {
     auto& params = GetParams();
     const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data());
     if (!ValidChannelCountForEffect(reverb_params->max_channels)) {
-        UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels);
+        ASSERT_MSG(false, "Invalid reverb max channel count {}", reverb_params->max_channels);
         return;
     }
 
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp
index 1751d0212..10646dc05 100644
--- a/src/audio_core/splitter_context.cpp
+++ b/src/audio_core/splitter_context.cpp
@@ -483,7 +483,7 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
                     // Add more work
                     index_stack.push(j);
                 } else if (node_state == NodeStates::State::InFound) {
-                    UNREACHABLE_MSG("Node start marked as found");
+                    ASSERT_MSG(false, "Node start marked as found");
                     ResetState();
                     return false;
                 }
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp
index c8e4a6caf..f58a5c754 100644
--- a/src/audio_core/voice_context.cpp
+++ b/src/audio_core/voice_context.cpp
@@ -114,7 +114,7 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in,
         in_params.current_playstate = ServerPlayState::Play;
         break;
     default:
-        UNREACHABLE_MSG("Unknown playstate {}", voice_in.play_state);
+        ASSERT_MSG(false, "Unknown playstate {}", voice_in.play_state);
         break;
     }
 
@@ -410,7 +410,7 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration(
         return in_params.should_depop;
     }
     default:
-        UNREACHABLE_MSG("Invalid playstate {}", in_params.current_playstate);
+        ASSERT_MSG(false, "Invalid playstate {}", in_params.current_playstate);
     }
 
     return false;
diff --git a/src/common/assert.cpp b/src/common/assert.cpp
index b44570528..a27a025ae 100644
--- a/src/common/assert.cpp
+++ b/src/common/assert.cpp
@@ -11,3 +11,8 @@ void assert_handle_failure() {
         Crash();
     }
 }
+
+[[noreturn]] void unreachable_impl() {
+    Crash();
+    throw std::runtime_error("Unreachable code");
+}
diff --git a/src/common/assert.h b/src/common/assert.h
index dbfd8abaf..478bfa856 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -11,6 +11,8 @@
 // everywhere. So let's just move the handling of the failed assert to a single cpp file.
 void assert_handle_failure();
 
+[[noreturn]] void unreachable_impl();
+
 // For asserts we'd like to keep all the junk executed when an assert happens away from the
 // important code in the function. One way of doing this is to put all the relevant code inside a
 // lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
@@ -44,9 +46,17 @@ assert_noinline_call(const Fn& fn) {
         }                                                                                          \
     while (0)
 
-#define UNREACHABLE() assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); })
+#define UNREACHABLE()                                                                              \
+    do {                                                                                           \
+        assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); });                    \
+        unreachable_impl();                                                                        \
+    } while (0)
+
 #define UNREACHABLE_MSG(...)                                                                       \
-    assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); })
+    do {                                                                                           \
+        assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); });     \
+        unreachable_impl();                                                                        \
+    } while (0)
 
 #ifdef _DEBUG
 #define DEBUG_ASSERT(_a_) ASSERT(_a_)
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 6ffab63af..751549583 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -147,7 +147,7 @@ void UpdateRescalingInfo() {
         info.down_shift = 0;
         break;
     default:
-        UNREACHABLE();
+        ASSERT(false);
         info.up_scale = 1;
         info.down_shift = 0;
     }
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index e3c4f80eb..443323390 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -140,7 +140,6 @@ u64 GetSignatureTypeDataSize(SignatureType type) {
         return 0x3C;
     }
     UNREACHABLE();
-    return 0;
 }
 
 u64 GetSignatureTypePaddingSize(SignatureType type) {
@@ -155,7 +154,6 @@ u64 GetSignatureTypePaddingSize(SignatureType type) {
         return 0x40;
     }
     UNREACHABLE();
-    return 0;
 }
 
 SignatureType Ticket::GetSignatureType() const {
diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp
index d4c0a974a..2735d053b 100644
--- a/src/core/file_sys/nca_patch.cpp
+++ b/src/core/file_sys/nca_patch.cpp
@@ -50,7 +50,7 @@ std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, const BlockTyp
             low = mid + 1;
         }
     }
-    UNREACHABLE_MSG("Offset could not be found in BKTR block.");
+    ASSERT_MSG(false, "Offset could not be found in BKTR block.");
     return {0, 0};
 }
 } // Anonymous namespace
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 2eaac73ef..878d832c2 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -108,7 +108,7 @@ ContentRecordType GetCRTypeFromNCAType(NCAContentType type) {
         // TODO(DarkLordZach): Peek at NCA contents to differentiate Manual and Legal.
         return ContentRecordType::HtmlDocument;
     default:
-        UNREACHABLE_MSG("Invalid NCAContentType={:02X}", type);
+        ASSERT_MSG(false, "Invalid NCAContentType={:02X}", type);
         return ContentRecordType{};
     }
 }
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index e42d7c9f6..cc0076238 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -144,7 +144,7 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_
             LOG_ERROR(Service_FS, "Failed to open path {} in order to re-cache it", new_path);
         }
     } else {
-        UNREACHABLE();
+        ASSERT(false);
         return nullptr;
     }
 
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 0ff2a338e..6c230f619 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -65,7 +65,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
             controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
             controller->Connect(true);
         } else {
-            UNREACHABLE_MSG("Unable to add a new controller based on the given parameters!");
+            ASSERT_MSG(false, "Unable to add a new controller based on the given parameters!");
         }
     }
 
diff --git a/src/core/hid/hid_core.cpp b/src/core/hid/hid_core.cpp
index 7eed52593..7d6373414 100644
--- a/src/core/hid/hid_core.cpp
+++ b/src/core/hid/hid_core.cpp
@@ -48,7 +48,7 @@ EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type) {
         return handheld.get();
     case NpadIdType::Invalid:
     default:
-        UNREACHABLE_MSG("Invalid NpadIdType={}", npad_id_type);
+        ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type);
         return nullptr;
     }
 }
@@ -77,7 +77,7 @@ const EmulatedController* HIDCore::GetEmulatedController(NpadIdType npad_id_type
         return handheld.get();
     case NpadIdType::Invalid:
     default:
-        UNREACHABLE_MSG("Invalid NpadIdType={}", npad_id_type);
+        ASSERT_MSG(false, "Invalid NpadIdType={}", npad_id_type);
         return nullptr;
     }
 }
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index a427cbc93..0ddc8df9e 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -141,7 +141,7 @@ public:
         if (index < DomainHandlerCount()) {
             domain_handlers[index] = nullptr;
         } else {
-            UNREACHABLE_MSG("Unexpected handler index {}", index);
+            ASSERT_MSG(false, "Unexpected handler index {}", index);
         }
     }
 
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 34a8be052..9b6b284d0 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -244,7 +244,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) {
             FOREACH_SLAB_TYPE(INITIALIZE_SLAB_HEAP)
             // If we somehow get an invalid type, abort.
         default:
-            UNREACHABLE_MSG("Unknown slab type: {}", slab_types[i]);
+            ASSERT_MSG(false, "Unknown slab type: {}", slab_types[i]);
         }
 
         // If we've hit the end of a gap, free it.
diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h
index e46e0d848..5fa19d386 100644
--- a/src/core/hle/kernel/k_address_arbiter.h
+++ b/src/core/hle/kernel/k_address_arbiter.h
@@ -35,7 +35,7 @@ public:
         case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual:
             return SignalAndModifyByWaitingCountIfEqual(addr, value, count);
         }
-        UNREACHABLE();
+        ASSERT(false);
         return ResultUnknown;
     }
 
@@ -49,7 +49,7 @@ public:
         case Svc::ArbitrationType::WaitIfEqual:
             return WaitIfEqual(addr, value, timeout);
         }
-        UNREACHABLE();
+        ASSERT(false);
         return ResultUnknown;
     }
 
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index bc37cadda..3e612a207 100644
--- a/src/core/hle/kernel/k_address_space_info.cpp
+++ b/src/core/hle/kernel/k_address_space_info.cpp
@@ -84,7 +84,7 @@ u64 KAddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) {
         ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index]));
         return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address;
     }
-    UNREACHABLE();
+    ASSERT(false);
     return 0;
 }
 
@@ -101,7 +101,7 @@ std::size_t KAddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type)
         ASSERT(IsAllowed39BitType(type));
         return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size;
     }
-    UNREACHABLE();
+    ASSERT(false);
     return 0;
 }
 
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index a55db3088..58e540f31 100644
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -29,7 +29,7 @@ constexpr KMemoryManager::Pool GetPoolFromMemoryRegionType(u32 type) {
     } else if ((type | KMemoryRegionType_DramSystemNonSecurePool) == type) {
         return KMemoryManager::Pool::SystemNonSecure;
     } else {
-        UNREACHABLE_MSG("InvalidMemoryRegionType for conversion to Pool");
+        ASSERT_MSG(false, "InvalidMemoryRegionType for conversion to Pool");
         return {};
     }
 }
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 68867a2bb..504e22cb9 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -35,7 +35,7 @@ constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceT
     case FileSys::ProgramAddressSpaceType::Is39Bit:
         return 39;
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return {};
     }
 }
@@ -128,7 +128,7 @@ ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_
     const std::size_t needed_size{
         (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size)};
     if (alloc_size < needed_size) {
-        UNREACHABLE();
+        ASSERT(false);
         return ResultOutOfMemory;
     }
 
@@ -1430,7 +1430,7 @@ ResultCode KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size,
             new_state = KMemoryState::AliasCodeData;
             break;
         default:
-            UNREACHABLE();
+            ASSERT(false);
         }
     }
 
@@ -1823,9 +1823,7 @@ void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages,
     VAddr addr{start};
     while (addr < start + (num_pages * PageSize)) {
         const PAddr paddr{GetPhysicalAddr(addr)};
-        if (!paddr) {
-            UNREACHABLE();
-        }
+        ASSERT(paddr != 0);
         page_linked_list.AddBlock(paddr, 1);
         addr += PageSize;
     }
@@ -1856,7 +1854,7 @@ ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageLin
             system.Memory().MapMemoryRegion(page_table_impl, addr, size, node.GetAddress());
             break;
         default:
-            UNREACHABLE();
+            ASSERT(false);
         }
 
         addr += size;
@@ -1887,7 +1885,7 @@ ResultCode KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermiss
     case OperationType::ChangePermissionsAndRefresh:
         break;
     default:
-        UNREACHABLE();
+        ASSERT(false);
     }
     return ResultSuccess;
 }
@@ -1924,7 +1922,6 @@ VAddr KPageTable::GetRegionAddress(KMemoryState state) const {
         return code_region_start;
     default:
         UNREACHABLE();
-        return {};
     }
 }
 
@@ -1960,7 +1957,6 @@ std::size_t KPageTable::GetRegionSize(KMemoryState state) const {
         return code_region_end - code_region_start;
     default:
         UNREACHABLE();
-        return {};
     }
 }
 
diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp
index a31861cdb..51c2cd1ef 100644
--- a/src/core/hle/kernel/k_port.cpp
+++ b/src/core/hle/kernel/k_port.cpp
@@ -60,7 +60,7 @@ ResultCode KPort::EnqueueSession(KServerSession* session) {
     if (auto session_ptr = server.GetSessionRequestHandler().lock()) {
         session_ptr->ClientConnected(server.AcceptSession());
     } else {
-        UNREACHABLE();
+        ASSERT(false);
     }
 
     return ResultSuccess;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index dcfeacccd..8c79b4f0f 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -350,7 +350,7 @@ ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
         break;
 
     default:
-        UNREACHABLE();
+        ASSERT(false);
     }
 
     // Create TLS region
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index 7e39f6d50..60f8ed470 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -97,13 +97,13 @@ ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& co
                          "object_id {} is too big! This probably means a recent service call "
                          "to {} needed to return a new interface!",
                          object_id, name);
-            UNREACHABLE();
+            ASSERT(false);
             return ResultSuccess; // Ignore error if asserts are off
         }
         if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock()) {
             return strong_ptr->HandleSyncRequest(*this, context);
         } else {
-            UNREACHABLE();
+            ASSERT(false);
             return ResultSuccess;
         }
 
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 940334f59..ea2160099 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -133,7 +133,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
         UNIMPLEMENTED();
         break;
     default:
-        UNREACHABLE_MSG("KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
+        ASSERT_MSG(false, "KThread::Initialize: Unknown ThreadType {}", static_cast<u32>(type));
         break;
     }
     thread_type = type;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 66e0ce2d0..584fa5b1c 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1876,7 +1876,7 @@ static void SleepThread(Core::System& system, s64 nanoseconds) {
         KScheduler::YieldToAnyThread(kernel);
     } else {
         // Nintendo does nothing at all if an otherwise invalid value is passed.
-        UNREACHABLE_MSG("Unimplemented sleep yield type '{:016X}'!", nanoseconds);
+        ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds);
     }
 }
 
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 655f2e936..0a5603d18 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -178,7 +178,7 @@ ResultCode Controller::GetStatus() const {
 }
 
 void Controller::ExecuteInteractive() {
-    UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet.");
+    ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet.");
 }
 
 void Controller::Execute() {
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp
index 911b2c229..0b87c60b9 100644
--- a/src/core/hle/service/am/applets/applet_error.cpp
+++ b/src/core/hle/service/am/applets/applet_error.cpp
@@ -156,7 +156,7 @@ ResultCode Error::GetStatus() const {
 }
 
 void Error::ExecuteInteractive() {
-    UNREACHABLE_MSG("Unexpected interactive applet data!");
+    ASSERT_MSG(false, "Unexpected interactive applet data!");
 }
 
 void Error::Execute() {
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index 3fe1a390a..41c002ef2 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -76,7 +76,7 @@ ResultCode Auth::GetStatus() const {
 }
 
 void Auth::ExecuteInteractive() {
-    UNREACHABLE_MSG("Unexpected interactive applet data.");
+    ASSERT_MSG(false, "Unexpected interactive applet data.");
 }
 
 void Auth::Execute() {
@@ -175,7 +175,7 @@ ResultCode PhotoViewer::GetStatus() const {
 }
 
 void PhotoViewer::ExecuteInteractive() {
-    UNREACHABLE_MSG("Unexpected interactive applet data.");
+    ASSERT_MSG(false, "Unexpected interactive applet data.");
 }
 
 void PhotoViewer::Execute() {
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp
index 3acde1630..8d847c3f6 100644
--- a/src/core/hle/service/am/applets/applet_mii_edit.cpp
+++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp
@@ -67,7 +67,7 @@ ResultCode MiiEdit::GetStatus() const {
 }
 
 void MiiEdit::ExecuteInteractive() {
-    UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet.");
+    ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet.");
 }
 
 void MiiEdit::Execute() {
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index fd16f2e49..02049fd9f 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -44,7 +44,7 @@ ResultCode ProfileSelect::GetStatus() const {
 }
 
 void ProfileSelect::ExecuteInteractive() {
-    UNREACHABLE_MSG("Attempted to call interactive execution on non-interactive applet.");
+    ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet.");
 }
 
 void ProfileSelect::Execute() {
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
index 7c21365e4..4116fbaa7 100644
--- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
@@ -71,7 +71,7 @@ void SoftwareKeyboard::Initialize() {
         InitializeBackground(applet_mode);
         break;
     default:
-        UNREACHABLE_MSG("Invalid LibraryAppletMode={}", applet_mode);
+        ASSERT_MSG(false, "Invalid LibraryAppletMode={}", applet_mode);
         break;
     }
 }
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 2aa4a00ad..7b3f77a51 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -279,7 +279,7 @@ void WebBrowser::Initialize() {
         InitializeLobby();
         break;
     default:
-        UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind);
+        ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
         break;
     }
 }
@@ -320,7 +320,7 @@ void WebBrowser::Execute() {
         ExecuteLobby();
         break;
     default:
-        UNREACHABLE_MSG("Invalid ShimKind={}", web_arg_header.shim_kind);
+        ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind);
         WebBrowserExit(WebExitReason::EndButtonPressed);
         break;
     }
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index ddfcba0f1..fae6e5aff 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -899,7 +899,7 @@ void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
     case FileSys::SaveDataSpaceId::TemporaryStorage:
     case FileSys::SaveDataSpaceId::ProperSystem:
     case FileSys::SaveDataSpaceId::SafeMode:
-        UNREACHABLE();
+        ASSERT(false);
     }
 
     auto filesystem = std::make_shared<IFileSystem>(system, std::move(dir.Unwrap()),
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 1e04ee3f2..ac5c38cc6 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -160,7 +160,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
     shared_memory->system_properties.raw = 0;
     switch (controller_type) {
     case Core::HID::NpadStyleIndex::None:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     case Core::HID::NpadStyleIndex::ProController:
         shared_memory->style_tag.fullkey.Assign(1);
@@ -422,7 +422,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
         libnx_state.connection_status.is_connected.Assign(1);
         switch (controller_type) {
         case Core::HID::NpadStyleIndex::None:
-            UNREACHABLE();
+            ASSERT(false);
             break;
         case Core::HID::NpadStyleIndex::ProController:
         case Core::HID::NpadStyleIndex::NES:
@@ -597,7 +597,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
 
         switch (controller_type) {
         case Core::HID::NpadStyleIndex::None:
-            UNREACHABLE();
+            ASSERT(false);
             break;
         case Core::HID::NpadStyleIndex::ProController:
         case Core::HID::NpadStyleIndex::Pokeball:
@@ -856,7 +856,7 @@ void Controller_NPad::VibrateController(
     }
 
     if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) {
-        UNREACHABLE_MSG("DeviceIndex should never be None!");
+        ASSERT_MSG(false, "DeviceIndex should never be None!");
         return;
     }
 
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 8a496c38c..dc5d0366d 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1441,7 +1441,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
         break;
     case Core::HID::DeviceIndex::None:
     default:
-        UNREACHABLE_MSG("DeviceIndex should never be None!");
+        ASSERT_MSG(false, "DeviceIndex should never be None!");
         vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
         break;
     }
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index fa72fcba9..72e4902cb 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -347,7 +347,7 @@ public:
         }
 
         if (!succeeded) {
-            UNREACHABLE_MSG("Out of address space!");
+            ASSERT_MSG(false, "Out of address space!");
             return Kernel::ResultOutOfMemory;
         }
 
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 4964539f9..08300a1a6 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -290,7 +290,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo
     u8 glasses_type{};
     while (glasses_type_start < glasses_type_info.values[glasses_type]) {
         if (++glasses_type >= glasses_type_info.values_count) {
-            UNREACHABLE();
+            ASSERT(false);
             break;
         }
     }
diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/syncpoint_manager.cpp
index f77f0df27..a6fa943e8 100644
--- a/src/core/hle/service/nvdrv/syncpoint_manager.cpp
+++ b/src/core/hle/service/nvdrv/syncpoint_manager.cpp
@@ -23,7 +23,7 @@ u32 SyncpointManager::AllocateSyncpoint() {
             return syncpoint_id;
         }
     }
-    UNREACHABLE_MSG("No more available syncpoints!");
+    ASSERT_MSG(false, "No more available syncpoints!");
     return {};
 }
 
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index fe95d1b73..337431488 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -659,7 +659,7 @@ Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
         value = core->consumer_usage_bit;
         break;
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return Status::BadValue;
     }
 
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp
index f0cc9a155..508091dc2 100644
--- a/src/core/hle/service/time/standard_user_system_clock_core.cpp
+++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp
@@ -48,12 +48,12 @@ ResultCode StandardUserSystemClockCore::GetClockContext(Core::System& system,
 }
 
 ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext&) {
-    UNREACHABLE();
+    UNIMPLEMENTED();
     return ERROR_NOT_IMPLEMENTED;
 }
 
 ResultCode StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) {
-    UNREACHABLE();
+    UNIMPLEMENTED();
     return ERROR_NOT_IMPLEMENTED;
 }
 
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index acc038dbf..28667710e 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -111,7 +111,7 @@ struct TimeManager::Impl final {
                               FileSys::VirtualFile& vfs_file) {
         if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
                 location_name, vfs_file) != ResultSuccess) {
-            UNREACHABLE();
+            ASSERT(false);
             return;
         }
 
@@ -155,7 +155,7 @@ struct TimeManager::Impl final {
         } else {
             if (standard_local_system_clock_core.SetCurrentTime(system_, posix_time) !=
                 ResultSuccess) {
-                UNREACHABLE();
+                ASSERT(false);
                 return;
             }
         }
@@ -170,7 +170,7 @@ struct TimeManager::Impl final {
 
         if (standard_network_system_clock_core.SetSystemClockContext(clock_context) !=
             ResultSuccess) {
-            UNREACHABLE();
+            ASSERT(false);
             return;
         }
 
@@ -183,7 +183,7 @@ struct TimeManager::Impl final {
                                       Clock::SteadyClockTimePoint steady_clock_time_point) {
         if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
                 system_, is_automatic_correction_enabled) != ResultSuccess) {
-            UNREACHABLE();
+            ASSERT(false);
             return;
         }
 
@@ -203,7 +203,7 @@ struct TimeManager::Impl final {
         if (GetStandardLocalSystemClockCore()
                 .SetCurrentTime(system_, timespan.ToSeconds())
                 .IsError()) {
-            UNREACHABLE();
+            ASSERT(false);
             return;
         }
     }
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index eeec34436..fee05ec7a 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -279,7 +279,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) {
         break;
     }
     default:
-        UNREACHABLE();
+        ASSERT(false);
     }
     return value + rule.transition_time + offset;
 }
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 7a0b73eca..5cc99fbe4 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -25,7 +25,6 @@ u64 MemoryReadWidth(Core::Memory::Memory& memory, u32 width, VAddr addr) {
         return memory.Read64(addr);
     default:
         UNREACHABLE();
-        return 0;
     }
 }
 
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp
index 83b2e0fc4..a5eb97b7f 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/command_classes/codecs/codec.cpp
@@ -224,7 +224,7 @@ void Codec::Decode() {
             vp9_hidden_frame = vp9_decoder->WasFrameHidden();
             return vp9_decoder->GetFrameBytes();
         default:
-            UNREACHABLE();
+            ASSERT(false);
             return std::vector<u8>{};
         }
     }();
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/command_classes/vic.cpp
index bef321b6e..7c17df353 100644
--- a/src/video_core/command_classes/vic.cpp
+++ b/src/video_core/command_classes/vic.cpp
@@ -228,7 +228,7 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
         break;
     }
     default:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     }
     gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(),
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 434ba0877..5f9eb208c 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -202,7 +202,7 @@ public:
                 case Size::Size_11_11_10:
                     return 3;
                 default:
-                    UNREACHABLE();
+                    ASSERT(false);
                     return 1;
                 }
             }
@@ -238,7 +238,7 @@ public:
                 case Size::Size_11_11_10:
                     return 4;
                 default:
-                    UNREACHABLE();
+                    ASSERT(false);
                     return 1;
                 }
             }
@@ -274,7 +274,7 @@ public:
                 case Size::Size_11_11_10:
                     return "11_11_10";
                 default:
-                    UNREACHABLE();
+                    ASSERT(false);
                     return {};
                 }
             }
@@ -296,7 +296,7 @@ public:
                 case Type::Float:
                     return "FLOAT";
                 }
-                UNREACHABLE();
+                ASSERT(false);
                 return {};
             }
 
@@ -336,7 +336,7 @@ public:
                 case 3:
                     return {x3, y3};
                 default:
-                    UNREACHABLE();
+                    ASSERT(false);
                     return {0, 0};
                 }
             }
@@ -1193,7 +1193,7 @@ public:
                         case IndexFormat::UnsignedInt:
                             return 4;
                         }
-                        UNREACHABLE();
+                        ASSERT(false);
                         return 1;
                     }
 
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index a7302f7c1..0efe58282 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -62,7 +62,7 @@ void MaxwellDMA::Launch() {
 
     if (!is_src_pitch && !is_dst_pitch) {
         // If both the source and the destination are in block layout, assert.
-        UNREACHABLE_MSG("Tiled->Tiled DMA transfers are not yet implemented");
+        UNIMPLEMENTED_MSG("Tiled->Tiled DMA transfers are not yet implemented");
         return;
     }
 
@@ -260,7 +260,7 @@ void MaxwellDMA::ReleaseSemaphore() {
         memory_manager.Write<u64>(address + 8, system.GPU().GetTicks());
         break;
     default:
-        UNREACHABLE_MSG("Unknown semaphore type: {}", static_cast<u32>(type.Value()));
+        ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value()));
     }
 }
 
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 8479dc6d2..b0ce9f000 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -50,7 +50,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
         } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) {
             rasterizer->OnCPUWrite(invalidate->addr, invalidate->size);
         } else {
-            UNREACHABLE();
+            ASSERT(false);
         }
         state.signaled_fence.store(next.fence);
         if (next.block) {
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index e7279efcd..43f8b5904 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -71,7 +71,7 @@ void MacroEngine::Execute(u32 method, const std::vector<u32>& parameters) {
                 }
             }
             if (!mid_method.has_value()) {
-                UNREACHABLE_MSG("Macro 0x{0:x} was not uploaded", method);
+                ASSERT_MSG(false, "Macro 0x{0:x} was not uploaded", method);
                 return;
             }
         }
diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp
index 87d2e8721..f670b1bca 100644
--- a/src/video_core/macro/macro_interpreter.cpp
+++ b/src/video_core/macro/macro_interpreter.cpp
@@ -308,7 +308,6 @@ bool MacroInterpreterImpl::EvaluateBranchCondition(Macro::BranchCondition cond,
         return value != 0;
     }
     UNREACHABLE();
-    return true;
 }
 
 Macro::Opcode MacroInterpreterImpl::GetOpcode() const {
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index c8d99fdb5..d373be0ba 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -67,7 +67,7 @@ void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) {
         ASSERT(it->first == gpu_addr);
         map_ranges.erase(it);
     } else {
-        UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr);
+        ASSERT_MSG(false, "Unmapping non-existent GPU address=0x{:x}", gpu_addr);
     }
     const auto submapped_ranges = GetSubmappedRange(gpu_addr, size);
 
@@ -206,7 +206,7 @@ T MemoryManager::Read(GPUVAddr addr) const {
         return value;
     }
 
-    UNREACHABLE();
+    ASSERT(false);
 
     return {};
 }
@@ -219,7 +219,7 @@ void MemoryManager::Write(GPUVAddr addr, T data) {
         return;
     }
 
-    UNREACHABLE();
+    ASSERT(false);
 }
 
 template u8 MemoryManager::Read<u8>(GPUVAddr addr) const;
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 35f42f2f8..67eae369d 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -48,7 +48,7 @@ GLenum Stage(size_t stage_index) {
     case 4:
         return GL_FRAGMENT_SHADER;
     }
-    UNREACHABLE_MSG("{}", stage_index);
+    ASSERT_MSG(false, "{}", stage_index);
     return GL_NONE;
 }
 
@@ -65,7 +65,7 @@ GLenum AssemblyStage(size_t stage_index) {
     case 4:
         return GL_FRAGMENT_PROGRAM_NV;
     }
-    UNREACHABLE_MSG("{}", stage_index);
+    ASSERT_MSG(false, "{}", stage_index);
     return GL_NONE;
 }
 
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index cd48fef26..07d4b7cf0 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -85,7 +85,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
             case Maxwell::TessellationPrimitive::Quads:
                 return Shader::TessPrimitive::Quads;
             }
-            UNREACHABLE();
+            ASSERT(false);
             return Shader::TessPrimitive::Triangles;
         }();
         info.tess_spacing = [&] {
@@ -97,7 +97,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
             case Maxwell::TessellationSpacing::FractionalEven:
                 return Shader::TessSpacing::FractionalEven;
             }
-            UNREACHABLE();
+            ASSERT(false);
             return Shader::TessSpacing::Equal;
         }();
         break;
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 29ff736fb..8c0fffc67 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -83,7 +83,7 @@ GLenum ImageTarget(const VideoCommon::ImageInfo& info) {
     case ImageType::Buffer:
         return GL_TEXTURE_BUFFER;
     }
-    UNREACHABLE_MSG("Invalid image type={}", info.type);
+    ASSERT_MSG(false, "Invalid image type={}", info.type);
     return GL_NONE;
 }
 
@@ -107,7 +107,7 @@ GLenum ImageTarget(Shader::TextureType type, int num_samples = 1) {
     case Shader::TextureType::Buffer:
         return GL_TEXTURE_BUFFER;
     }
-    UNREACHABLE_MSG("Invalid image view type={}", type);
+    ASSERT_MSG(false, "Invalid image view type={}", type);
     return GL_NONE;
 }
 
@@ -119,7 +119,7 @@ GLenum TextureMode(PixelFormat format, bool is_first) {
     case PixelFormat::S8_UINT_D24_UNORM:
         return is_first ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT;
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return GL_DEPTH_COMPONENT;
     }
 }
@@ -140,7 +140,7 @@ GLint Swizzle(SwizzleSource source) {
     case SwizzleSource::OneFloat:
         return GL_ONE;
     }
-    UNREACHABLE_MSG("Invalid swizzle source={}", source);
+    ASSERT_MSG(false, "Invalid swizzle source={}", source);
     return GL_NONE;
 }
 
@@ -197,7 +197,7 @@ GLint ConvertA5B5G5R1_UNORM(SwizzleSource source) {
     case SwizzleSource::OneFloat:
         return GL_ONE;
     }
-    UNREACHABLE_MSG("Invalid swizzle source={}", source);
+    ASSERT_MSG(false, "Invalid swizzle source={}", source);
     return GL_NONE;
 }
 
@@ -381,10 +381,10 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form
         glTextureStorage3D(handle, gl_num_levels, gl_internal_format, width, height, depth);
         break;
     case GL_TEXTURE_BUFFER:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     default:
-        UNREACHABLE_MSG("Invalid target=0x{:x}", target);
+        ASSERT_MSG(false, "Invalid target=0x{:x}", target);
         break;
     }
     return texture;
@@ -420,7 +420,7 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form
     case Shader::ImageFormat::R32G32B32A32_UINT:
         return GL_RGBA32UI;
     }
-    UNREACHABLE_MSG("Invalid image format={}", format);
+    ASSERT_MSG(false, "Invalid image format={}", format);
     return GL_R32UI;
 }
 
@@ -579,7 +579,7 @@ void TextureCacheRuntime::EmulateCopyImage(Image& dst, Image& src,
     } else if (IsPixelFormatBGR(dst.info.format) || IsPixelFormatBGR(src.info.format)) {
         format_conversion_pass.ConvertImage(dst, src, copies);
     } else {
-        UNREACHABLE();
+        ASSERT(false);
     }
 }
 
@@ -620,7 +620,7 @@ void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferM
     case ImageType::Linear:
         return util_shaders.PitchUpload(image, map, swizzles);
     default:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     }
 }
@@ -639,7 +639,7 @@ FormatProperties TextureCacheRuntime::FormatInfo(ImageType type, GLenum internal
     case ImageType::e3D:
         return format_properties[2].at(internal_format);
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return FormatProperties{};
     }
 }
@@ -888,7 +888,7 @@ void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t b
         }
         break;
     default:
-        UNREACHABLE();
+        ASSERT(false);
     }
 }
 
@@ -924,7 +924,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
         depth = copy.image_extent.depth;
         break;
     default:
-        UNREACHABLE();
+        ASSERT(false);
     }
     // Compressed formats don't have a pixel format or type
     const bool is_compressed = gl_format == GL_NONE;
@@ -950,7 +950,7 @@ void Image::Scale(bool up_scale) {
         case SurfaceType::DepthStencil:
             return GL_DEPTH_STENCIL_ATTACHMENT;
         default:
-            UNREACHABLE();
+            ASSERT(false);
             return GL_COLOR_ATTACHMENT0;
         }
     }();
@@ -965,7 +965,7 @@ void Image::Scale(bool up_scale) {
         case SurfaceType::DepthStencil:
             return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
         default:
-            UNREACHABLE();
+            ASSERT(false);
             return GL_COLOR_BUFFER_BIT;
         }
     }();
@@ -980,7 +980,7 @@ void Image::Scale(bool up_scale) {
         case SurfaceType::DepthStencil:
             return 3;
         default:
-            UNREACHABLE();
+            ASSERT(false);
             return 0;
         }
     }();
@@ -1045,7 +1045,7 @@ bool Image::ScaleUp(bool ignore) {
         return false;
     }
     if (info.type == ImageType::Linear) {
-        UNREACHABLE();
+        ASSERT(false);
         return false;
     }
     flags |= ImageFlagBits::Rescaled;
@@ -1139,7 +1139,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
         UNIMPLEMENTED();
         break;
     case ImageViewType::Buffer:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     }
     switch (info.type) {
@@ -1319,7 +1319,7 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
             buffer_bits |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
             break;
         default:
-            UNREACHABLE();
+            ASSERT(false);
             buffer_bits |= GL_DEPTH_BUFFER_BIT;
             break;
         }
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index c2a6da5a7..644b60d73 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -206,7 +206,7 @@ inline GLenum IndexFormat(Maxwell::IndexFormat index_format) {
     case Maxwell::IndexFormat::UnsignedInt:
         return GL_UNSIGNED_INT;
     }
-    UNREACHABLE_MSG("Invalid index_format={}", index_format);
+    ASSERT_MSG(false, "Invalid index_format={}", index_format);
     return {};
 }
 
@@ -243,7 +243,7 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
     case Maxwell::PrimitiveTopology::Patches:
         return GL_PATCHES;
     }
-    UNREACHABLE_MSG("Invalid topology={}", topology);
+    ASSERT_MSG(false, "Invalid topology={}", topology);
     return GL_POINTS;
 }
 
@@ -271,8 +271,8 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode,
         }
         break;
     }
-    UNREACHABLE_MSG("Invalid texture filter mode={} and mipmap filter mode={}", filter_mode,
-                    mipmap_filter_mode);
+    ASSERT_MSG(false, "Invalid texture filter mode={} and mipmap filter mode={}", filter_mode,
+               mipmap_filter_mode);
     return GL_NEAREST;
 }
 
@@ -550,7 +550,7 @@ inline GLenum PolygonMode(Maxwell::PolygonMode polygon_mode) {
     case Maxwell::PolygonMode::Fill:
         return GL_FILL;
     }
-    UNREACHABLE_MSG("Invalid polygon mode={}", polygon_mode);
+    ASSERT_MSG(false, "Invalid polygon mode={}", polygon_mode);
     return GL_FILL;
 }
 
@@ -563,7 +563,7 @@ inline GLenum ReductionFilter(Tegra::Texture::SamplerReduction filter) {
     case Tegra::Texture::SamplerReduction::Max:
         return GL_MAX;
     }
-    UNREACHABLE_MSG("Invalid reduction filter={}", static_cast<int>(filter));
+    ASSERT_MSG(false, "Invalid reduction filter={}", static_cast<int>(filter));
     return GL_WEIGHTED_AVERAGE_ARB;
 }
 
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 3a3c213bb..9a9243544 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -79,7 +79,7 @@ const char* GetSource(GLenum source) {
     case GL_DEBUG_SOURCE_OTHER:
         return "OTHER";
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return "Unknown source";
     }
 }
@@ -101,7 +101,7 @@ const char* GetType(GLenum type) {
     case GL_DEBUG_TYPE_MARKER:
         return "MARKER";
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return "Unknown type";
     }
 }
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 837825737..404def62e 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -282,7 +282,7 @@ GLenum StoreFormat(u32 bytes_per_block) {
     case 16:
         return GL_RGBA32UI;
     }
-    UNREACHABLE();
+    ASSERT(false);
     return GL_R8UI;
 }
 
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index ea360f339..193cbe15e 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -25,7 +25,7 @@ VkFilter Filter(Tegra::Texture::TextureFilter filter) {
     case Tegra::Texture::TextureFilter::Linear:
         return VK_FILTER_LINEAR;
     }
-    UNREACHABLE_MSG("Invalid sampler filter={}", filter);
+    ASSERT_MSG(false, "Invalid sampler filter={}", filter);
     return {};
 }
 
@@ -42,7 +42,7 @@ VkSamplerMipmapMode MipmapMode(Tegra::Texture::TextureMipmapFilter mipmap_filter
     case Tegra::Texture::TextureMipmapFilter::Linear:
         return VK_SAMPLER_MIPMAP_MODE_LINEAR;
     }
-    UNREACHABLE_MSG("Invalid sampler mipmap mode={}", mipmap_filter);
+    ASSERT_MSG(false, "Invalid sampler mipmap mode={}", mipmap_filter);
     return {};
 }
 
@@ -70,7 +70,7 @@ VkSamplerAddressMode WrapMode(const Device& device, Tegra::Texture::WrapMode wra
         case Tegra::Texture::TextureFilter::Linear:
             return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
         }
-        UNREACHABLE();
+        ASSERT(false);
         return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
     case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
         return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
@@ -744,7 +744,7 @@ VkViewportCoordinateSwizzleNV ViewportSwizzle(Maxwell::ViewportSwizzle swizzle)
     case Maxwell::ViewportSwizzle::NegativeW:
         return VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV;
     }
-    UNREACHABLE_MSG("Invalid swizzle={}", swizzle);
+    ASSERT_MSG(false, "Invalid swizzle={}", swizzle);
     return {};
 }
 
@@ -757,7 +757,7 @@ VkSamplerReductionMode SamplerReduction(Tegra::Texture::SamplerReduction reducti
     case Tegra::Texture::SamplerReduction::Max:
         return VK_SAMPLER_REDUCTION_MODE_MAX_EXT;
     }
-    UNREACHABLE_MSG("Invalid sampler mode={}", static_cast<int>(reduction));
+    ASSERT_MSG(false, "Invalid sampler mode={}", static_cast<int>(reduction));
     return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT;
 }
 
@@ -780,7 +780,7 @@ VkSampleCountFlagBits MsaaMode(Tegra::Texture::MsaaMode msaa_mode) {
     case Tegra::Texture::MsaaMode::Msaa4x4:
         return VK_SAMPLE_COUNT_16_BIT;
     default:
-        UNREACHABLE_MSG("Invalid msaa_mode={}", static_cast<int>(msaa_mode));
+        ASSERT_MSG(false, "Invalid msaa_mode={}", static_cast<int>(msaa_mode));
         return VK_SAMPLE_COUNT_1_BIT;
     }
 }
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index 0aeb37538..450905197 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -46,7 +46,7 @@ size_t BytesPerIndex(VkIndexType index_type) {
     case VK_INDEX_TYPE_UINT32:
         return 4;
     default:
-        UNREACHABLE_MSG("Invalid index type={}", index_type);
+        ASSERT_MSG(false, "Invalid index type={}", index_type);
         return 1;
     }
 }
@@ -366,7 +366,7 @@ void BufferCacheRuntime::ReserveQuadArrayLUT(u32 num_indices, bool wait_for_idle
                 std::memcpy(staging_data, MakeQuadIndices<u32>(quad, first).data(), quad_size);
                 break;
             default:
-                UNREACHABLE();
+                ASSERT(false);
                 break;
             }
             staging_data += quad_size;
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index 29481a102..acc8badc9 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -265,7 +265,7 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
         case Tegra::Engines::Maxwell3D::Regs::IndexFormat::UnsignedInt:
             return 2;
         }
-        UNREACHABLE();
+        ASSERT(false);
         return 2;
     }();
     const u32 input_size = num_vertices << index_shift;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 5196bdcf2..978e827f5 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -174,7 +174,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
             case Maxwell::TessellationPrimitive::Quads:
                 return Shader::TessPrimitive::Quads;
             }
-            UNREACHABLE();
+            ASSERT(false);
             return Shader::TessPrimitive::Triangles;
         }();
         info.tess_spacing = [&] {
@@ -187,7 +187,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
             case Maxwell::TessellationSpacing::FractionalEven:
                 return Shader::TessSpacing::FractionalEven;
             }
-            UNREACHABLE();
+            ASSERT(false);
             return Shader::TessSpacing::Equal;
         }();
         break;
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index 31ce2f815..9a6afaca6 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -263,7 +263,7 @@ StagingBufferPool::StagingBuffersCache& StagingBufferPool::GetCache(MemoryUsage
     case MemoryUsage::Download:
         return download_cache;
     default:
-        UNREACHABLE_MSG("Invalid memory usage={}", usage);
+        ASSERT_MSG(false, "Invalid memory usage={}", usage);
         return upload_cache;
     }
 }
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 353594293..43ecb9647 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -70,7 +70,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
     case ImageType::Buffer:
         break;
     }
-    UNREACHABLE_MSG("Invalid image type={}", type);
+    ASSERT_MSG(false, "Invalid image type={}", type);
     return {};
 }
 
@@ -87,7 +87,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
     case 16:
         return VK_SAMPLE_COUNT_16_BIT;
     default:
-        UNREACHABLE_MSG("Invalid number of samples={}", num_samples);
+        ASSERT_MSG(false, "Invalid number of samples={}", num_samples);
         return VK_SAMPLE_COUNT_1_BIT;
     }
 }
@@ -107,7 +107,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
             usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
             break;
         default:
-            UNREACHABLE_MSG("Invalid surface type");
+            ASSERT_MSG(false, "Invalid surface type");
         }
     }
     if (info.storage) {
@@ -179,7 +179,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
     case VideoCore::Surface::SurfaceType::DepthStencil:
         return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
     default:
-        UNREACHABLE_MSG("Invalid surface type");
+        ASSERT_MSG(false, "Invalid surface type");
         return VkImageAspectFlags{};
     }
 }
@@ -221,7 +221,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
     case SwizzleSource::OneInt:
         return VK_COMPONENT_SWIZZLE_ONE;
     }
-    UNREACHABLE_MSG("Invalid swizzle={}", swizzle);
+    ASSERT_MSG(false, "Invalid swizzle={}", swizzle);
     return VK_COMPONENT_SWIZZLE_ZERO;
 }
 
@@ -242,10 +242,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
     case Shader::TextureType::ColorArrayCube:
         return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
     case Shader::TextureType::Buffer:
-        UNREACHABLE_MSG("Texture buffers can't be image views");
+        ASSERT_MSG(false, "Texture buffers can't be image views");
         return VK_IMAGE_VIEW_TYPE_1D;
     }
-    UNREACHABLE_MSG("Invalid image view type={}", type);
+    ASSERT_MSG(false, "Invalid image view type={}", type);
     return VK_IMAGE_VIEW_TYPE_2D;
 }
 
@@ -269,10 +269,10 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
         UNIMPLEMENTED_MSG("Rect image view");
         return VK_IMAGE_VIEW_TYPE_2D;
     case VideoCommon::ImageViewType::Buffer:
-        UNREACHABLE_MSG("Texture buffers can't be image views");
+        ASSERT_MSG(false, "Texture buffers can't be image views");
         return VK_IMAGE_VIEW_TYPE_1D;
     }
-    UNREACHABLE_MSG("Invalid image view type={}", type);
+    ASSERT_MSG(false, "Invalid image view type={}", type);
     return VK_IMAGE_VIEW_TYPE_2D;
 }
 
@@ -644,7 +644,7 @@ struct RangedBarrierRange {
     case Shader::ImageFormat::R32G32B32A32_UINT:
         return VK_FORMAT_R32G32B32A32_UINT;
     }
-    UNREACHABLE_MSG("Invalid image format={}", format);
+    ASSERT_MSG(false, "Invalid image format={}", format);
     return VK_FORMAT_R32_UINT;
 }
 
@@ -1596,7 +1596,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
         UNIMPLEMENTED();
         break;
     case VideoCommon::ImageViewType::Buffer:
-        UNREACHABLE();
+        ASSERT(false);
         break;
     }
 }
@@ -1822,7 +1822,7 @@ void TextureCacheRuntime::AccelerateImageUpload(
     if (IsPixelFormatASTC(image.info.format)) {
         return astc_decoder_pass.Assemble(image, map, swizzles);
     }
-    UNREACHABLE();
+    ASSERT(false);
 }
 
 } // namespace Vulkan
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index d469964f6..c4e923bbf 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -280,7 +280,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
         stage_index = 4;
         break;
     default:
-        UNREACHABLE_MSG("Invalid program={}", program);
+        ASSERT_MSG(false, "Invalid program={}", program);
         break;
     }
     const u64 local_size{sph.LocalMemorySize()};
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index 5f428d35d..69c1b1e6d 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -29,7 +29,7 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t
         return SurfaceTarget::Texture2DArray;
     default:
         LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", texture_type);
-        UNREACHABLE();
+        ASSERT(false);
         return SurfaceTarget::Texture2D;
     }
 }
@@ -48,7 +48,7 @@ bool SurfaceTargetIsLayered(SurfaceTarget target) {
         return true;
     default:
         LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target);
-        UNREACHABLE();
+        ASSERT(false);
         return false;
     }
 }
@@ -67,7 +67,7 @@ bool SurfaceTargetIsArray(SurfaceTarget target) {
         return true;
     default:
         LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", target);
-        UNREACHABLE();
+        ASSERT(false);
         return false;
     }
 }
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 802939f6c..6c073ee57 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -94,7 +94,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
         resources.layers = 1;
         break;
     default:
-        UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
+        ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
         break;
     }
     if (type != ImageType::Linear) {
diff --git a/src/video_core/texture_cache/image_view_info.cpp b/src/video_core/texture_cache/image_view_info.cpp
index 0cee5e45f..f47885147 100644
--- a/src/video_core/texture_cache/image_view_info.cpp
+++ b/src/video_core/texture_cache/image_view_info.cpp
@@ -71,7 +71,7 @@ ImageViewInfo::ImageViewInfo(const TICEntry& config, s32 base_layer) noexcept
         range.extent.layers = config.Depth() * 6;
         break;
     default:
-        UNREACHABLE_MSG("Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
+        ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
         break;
     }
 }
diff --git a/src/video_core/texture_cache/samples_helper.h b/src/video_core/texture_cache/samples_helper.h
index 91fec60bd..d552bccf0 100644
--- a/src/video_core/texture_cache/samples_helper.h
+++ b/src/video_core/texture_cache/samples_helper.h
@@ -23,7 +23,7 @@ namespace VideoCommon {
     case 16:
         return {2, 2};
     }
-    UNREACHABLE_MSG("Invalid number of samples={}", num_samples);
+    ASSERT_MSG(false, "Invalid number of samples={}", num_samples);
     return {1, 1};
 }
 
@@ -47,7 +47,7 @@ namespace VideoCommon {
     case MsaaMode::Msaa4x4:
         return 16;
     }
-    UNREACHABLE_MSG("Invalid MSAA mode={}", static_cast<int>(msaa_mode));
+    ASSERT_MSG(false, "Invalid MSAA mode={}", static_cast<int>(msaa_mode));
     return 1;
 }
 
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 6622d7818..cf3ca06a6 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1485,14 +1485,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
             std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) {
             const auto page_it = selected_page_table.find(page);
             if (page_it == selected_page_table.end()) {
-                UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
+                ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
                 return;
             }
             std::vector<ImageId>& image_ids = page_it->second;
             const auto vector_it = std::ranges::find(image_ids, image_id);
             if (vector_it == image_ids.end()) {
-                UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}",
-                                page << PAGE_BITS);
+                ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}",
+                           page << PAGE_BITS);
                 return;
             }
             image_ids.erase(vector_it);
@@ -1504,14 +1504,14 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
         ForEachCPUPage(image.cpu_addr, image.guest_size_bytes, [this, map_id](u64 page) {
             const auto page_it = page_table.find(page);
             if (page_it == page_table.end()) {
-                UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
+                ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
                 return;
             }
             std::vector<ImageMapId>& image_map_ids = page_it->second;
             const auto vector_it = std::ranges::find(image_map_ids, map_id);
             if (vector_it == image_map_ids.end()) {
-                UNREACHABLE_MSG("Unregistering unregistered image in page=0x{:x}",
-                                page << PAGE_BITS);
+                ASSERT_MSG(false, "Unregistering unregistered image in page=0x{:x}",
+                           page << PAGE_BITS);
                 return;
             }
             image_map_ids.erase(vector_it);
@@ -1532,7 +1532,7 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
         ForEachCPUPage(cpu_addr, size, [this, image_id](u64 page) {
             const auto page_it = page_table.find(page);
             if (page_it == page_table.end()) {
-                UNREACHABLE_MSG("Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
+                ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << PAGE_BITS);
                 return;
             }
             std::vector<ImageMapId>& image_map_ids = page_it->second;
@@ -1616,15 +1616,15 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
     const GPUVAddr gpu_addr = image.gpu_addr;
     const auto alloc_it = image_allocs_table.find(gpu_addr);
     if (alloc_it == image_allocs_table.end()) {
-        UNREACHABLE_MSG("Trying to delete an image alloc that does not exist in address 0x{:x}",
-                        gpu_addr);
+        ASSERT_MSG(false, "Trying to delete an image alloc that does not exist in address 0x{:x}",
+                   gpu_addr);
         return;
     }
     const ImageAllocId alloc_id = alloc_it->second;
     std::vector<ImageId>& alloc_images = slot_image_allocs[alloc_id].images;
     const auto alloc_image_it = std::ranges::find(alloc_images, image_id);
     if (alloc_image_it == alloc_images.end()) {
-        UNREACHABLE_MSG("Trying to delete an image that does not exist");
+        ASSERT_MSG(false, "Trying to delete an image that does not exist");
         return;
     }
     ASSERT_MSG(False(image.flags & ImageFlagBits::Tracked), "Image was not untracked");
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index c81343850..9b6b8527b 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -87,7 +87,7 @@ void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixe
         BPP_CASE(16)
 #undef BPP_CASE
     default:
-        UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel);
+        ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel);
     }
 }
 
@@ -209,7 +209,7 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32
         BPP_CASE(16)
 #undef BPP_CASE
     default:
-        UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel);
+        ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel);
     }
 }
 
@@ -230,7 +230,7 @@ void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width,
         BPP_CASE(16)
 #undef BPP_CASE
     default:
-        UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel);
+        ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel);
     }
 }
 
@@ -253,7 +253,7 @@ void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 widt
         BPP_CASE(16)
 #undef BPP_CASE
     default:
-        UNREACHABLE_MSG("Invalid bytes_per_pixel={}", bytes_per_pixel);
+        ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel);
     }
 }
 
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index b3a77e07f..11ce865a7 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -738,9 +738,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags
     // The wanted format is not supported by hardware, search for alternatives
     const VkFormat* alternatives = GetFormatAlternatives(wanted_format);
     if (alternatives == nullptr) {
-        UNREACHABLE_MSG("Format={} with usage={} and type={} has no defined alternatives and host "
-                        "hardware does not support it",
-                        wanted_format, wanted_usage, format_type);
+        ASSERT_MSG(false,
+                   "Format={} with usage={} and type={} has no defined alternatives and host "
+                   "hardware does not support it",
+                   wanted_format, wanted_usage, format_type);
         return wanted_format;
     }
 
@@ -756,9 +757,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags
     }
 
     // No alternatives found, panic
-    UNREACHABLE_MSG("Format={} with usage={} and type={} is not supported by the host hardware and "
-                    "doesn't support any of the alternatives",
-                    wanted_format, wanted_usage, format_type);
+    ASSERT_MSG(false,
+               "Format={} with usage={} and type={} is not supported by the host hardware and "
+               "doesn't support any of the alternatives",
+               wanted_format, wanted_usage, format_type);
     return wanted_format;
 }
 
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
index caae6dfdc..6442898bd 100644
--- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
+++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
@@ -49,7 +49,7 @@ struct Range {
         return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
                VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
     }
-    UNREACHABLE_MSG("Invalid memory usage={}", usage);
+    ASSERT_MSG(false, "Invalid memory usage={}", usage);
     return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
 }
 
@@ -325,7 +325,7 @@ VkMemoryPropertyFlags MemoryAllocator::MemoryPropertyFlags(u32 type_mask,
         // Remove device local, if it's not supported by the requested resource
         return MemoryPropertyFlags(type_mask, flags & ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
     }
-    UNREACHABLE_MSG("No compatible memory types found");
+    ASSERT_MSG(false, "No compatible memory types found");
     return 0;
 }
 
@@ -349,7 +349,7 @@ bool IsHostVisible(MemoryUsage usage) noexcept {
     case MemoryUsage::Download:
         return true;
     }
-    UNREACHABLE_MSG("Invalid memory usage={}", usage);
+    ASSERT_MSG(false, "Invalid memory usage={}", usage);
     return false;
 }
 
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index c924cb0cb..8be311fcb 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -631,7 +631,7 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
     switch (max_supported_players) {
     case 0:
     default:
-        UNREACHABLE();
+        ASSERT(false);
         return;
     case 1:
         ui->widgetSpacer->hide();

From 58fea44eb5bfe268c1ddd2ea063744eb7bbe7e44 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 18:05:32 -0400
Subject: [PATCH 2/9] common: Don't test ASSERT conditions inline

---
 src/common/assert.cpp | 10 +++++---
 src/common/assert.h   | 58 +++++++++++++++++++++----------------------
 2 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/src/common/assert.cpp b/src/common/assert.cpp
index a27a025ae..b20c19123 100644
--- a/src/common/assert.cpp
+++ b/src/common/assert.cpp
@@ -6,9 +6,13 @@
 
 #include "common/settings.h"
 
-void assert_handle_failure() {
-    if (Settings::values.use_debug_asserts) {
-        Crash();
+void assert_check_condition(bool cond, std::function<void()>&& on_failure) {
+    if (!cond) {
+        on_failure();
+
+        if (Settings::values.use_debug_asserts) {
+            Crash();
+        }
     }
 }
 
diff --git a/src/common/assert.h b/src/common/assert.h
index 478bfa856..fb7808657 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -4,57 +4,57 @@
 
 #pragma once
 
+#include <functional>
+
 #include "common/logging/log.h"
 
 // Sometimes we want to try to continue even after hitting an assert.
 // However touching this file yields a global recompilation as this header is included almost
 // everywhere. So let's just move the handling of the failed assert to a single cpp file.
-void assert_handle_failure();
-
-[[noreturn]] void unreachable_impl();
 
 // For asserts we'd like to keep all the junk executed when an assert happens away from the
 // important code in the function. One way of doing this is to put all the relevant code inside a
-// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
-// specify __declspec on lambda functions, so what we do instead is define a noinline wrapper
-// template that calls the lambda. This seems to generate an extra instruction at the call-site
-// compared to the ideal implementation (which wouldn't support ASSERT_MSG parameters), but is good
-// enough for our purposes.
-template <typename Fn>
-#if defined(_MSC_VER)
-[[msvc::noinline]]
-#elif defined(__GNUC__)
-[[gnu::cold, gnu::noinline]]
-#endif
-static void
-assert_noinline_call(const Fn& fn) {
-    fn();
-    assert_handle_failure();
-}
+// lambda and force the compiler to not inline it.
+void assert_check_condition(bool cond, std::function<void()>&& on_failure);
+
+[[noreturn]] void unreachable_impl();
 
 #define ASSERT(_a_)                                                                                \
-    do                                                                                             \
-        if (!(_a_)) {                                                                              \
-            assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); });                \
+    do {                                                                                           \
+        if (std::is_constant_evaluated()) {                                                        \
+            if (!(_a_)) {                                                                          \
+                /* Will trigger compile error here */                                              \
+                assert_check_condition(bool(_a_),                                                  \
+                                       [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });          \
+            }                                                                                      \
+        } else {                                                                                   \
+            assert_check_condition(bool(_a_), [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });   \
         }                                                                                          \
-    while (0)
+    } while (0)
 
 #define ASSERT_MSG(_a_, ...)                                                                       \
-    do                                                                                             \
-        if (!(_a_)) {                                                                              \
-            assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
+    do {                                                                                           \
+        if (std::is_constant_evaluated()) {                                                        \
+            if (!(_a_)) {                                                                          \
+                /* Will trigger compile error here */                                              \
+                assert_check_condition(bool(_a_),                                                  \
+                                       [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });          \
+            }                                                                                      \
+        } else {                                                                                   \
+            assert_check_condition(                                                                \
+                bool(_a_), [&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); });       \
         }                                                                                          \
-    while (0)
+    } while (0)
 
 #define UNREACHABLE()                                                                              \
     do {                                                                                           \
-        assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); });                    \
+        LOG_CRITICAL(Debug, "Unreachable code!");                                                  \
         unreachable_impl();                                                                        \
     } while (0)
 
 #define UNREACHABLE_MSG(...)                                                                       \
     do {                                                                                           \
-        assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); });     \
+        LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__);                                    \
         unreachable_impl();                                                                        \
     } while (0)
 

From 8fea7e56e5061bd609a4369f6e58af97be328701 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 18:19:40 -0400
Subject: [PATCH 3/9] kernel: fix inconsistency in AutoObjectTraits macro
 definitions

---
 src/core/hle/kernel/k_auto_object.h | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h
index ea47fc600..2827763d5 100644
--- a/src/core/hle/kernel/k_auto_object.h
+++ b/src/core/hle/kernel/k_auto_object.h
@@ -18,7 +18,7 @@ namespace Kernel {
 class KernelCore;
 class KProcess;
 
-#define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS)                                                \
+#define KERNEL_AUTOOBJECT_TRAITS_IMPL(CLASS, BASE_CLASS, ATTRIBUTE)                                \
                                                                                                    \
 private:                                                                                           \
     friend class ::Kernel::KClassTokenGenerator;                                                   \
@@ -40,16 +40,19 @@ public:
     static constexpr const char* GetStaticTypeName() {                                             \
         return TypeName;                                                                           \
     }                                                                                              \
-    virtual TypeObj GetTypeObj() const {                                                           \
+    virtual TypeObj GetTypeObj() ATTRIBUTE {                                                       \
         return GetStaticTypeObj();                                                                 \
     }                                                                                              \
-    virtual const char* GetTypeName() const {                                                      \
+    virtual const char* GetTypeName() ATTRIBUTE {                                                  \
         return GetStaticTypeName();                                                                \
     }                                                                                              \
                                                                                                    \
 private:                                                                                           \
     constexpr bool operator!=(const TypeObj& rhs)
 
+#define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS)                                                \
+    KERNEL_AUTOOBJECT_TRAITS_IMPL(CLASS, BASE_CLASS, const override)
+
 class KAutoObject {
 protected:
     class TypeObj {
@@ -82,7 +85,7 @@ protected:
     };
 
 private:
-    KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject);
+    KERNEL_AUTOOBJECT_TRAITS_IMPL(KAutoObject, KAutoObject, const);
 
 public:
     explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {

From 6f59e2676bed88d7a31114d6fd1e147a04c09bac Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 18:22:54 -0400
Subject: [PATCH 4/9] kernel: ensure class token lambda exit is unreachable

---
 src/core/hle/kernel/k_class_token.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h
index be9e3c357..c9001ae3d 100644
--- a/src/core/hle/kernel/k_class_token.h
+++ b/src/core/hle/kernel/k_class_token.h
@@ -49,6 +49,7 @@ private:
                 }
             }
         }
+        UNREACHABLE();
     }();
 
     template <typename T>

From d11547024c2c14b913ed8743de5e345260e3c19f Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 18:56:38 -0400
Subject: [PATCH 5/9] general: fix compilation on GCC 12

---
 src/core/file_sys/content_archive.cpp                 | 2 +-
 src/shader_recompiler/frontend/maxwell/control_flow.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index 93f784418..78e56bbbd 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -419,7 +419,7 @@ std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type
         Core::Crypto::Mode::ECB);
     cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt);
 
-    Core::Crypto::Key128 out;
+    Core::Crypto::Key128 out{};
     if (type == NCASectionCryptoType::XTS) {
         std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin());
     } else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) {
diff --git a/src/shader_recompiler/frontend/maxwell/control_flow.h b/src/shader_recompiler/frontend/maxwell/control_flow.h
index 2487b9b0b..1ce45b3a5 100644
--- a/src/shader_recompiler/frontend/maxwell/control_flow.h
+++ b/src/shader_recompiler/frontend/maxwell/control_flow.h
@@ -58,7 +58,7 @@ public:
     [[nodiscard]] Stack Remove(Token token) const;
 
 private:
-    boost::container::small_vector<StackEntry, 3> entries;
+    std::vector<StackEntry> entries;
 };
 
 struct IndirectBranch {

From a29ddcee40d78b1c1f7f64855331888777add4f4 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Tue, 7 Jun 2022 19:46:10 -0400
Subject: [PATCH 6/9] common/assert: add unlikely

---
 src/common/assert.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/common/assert.cpp b/src/common/assert.cpp
index b20c19123..1a85faccf 100644
--- a/src/common/assert.cpp
+++ b/src/common/assert.cpp
@@ -7,7 +7,7 @@
 #include "common/settings.h"
 
 void assert_check_condition(bool cond, std::function<void()>&& on_failure) {
-    if (!cond) {
+    if (!cond) [[unlikely]] {
         on_failure();
 
         if (Settings::values.use_debug_asserts) {

From ebecdd3a7458dd5a353524dc161f4050d019b7be Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 12 Jun 2022 17:14:27 -0400
Subject: [PATCH 7/9] general: fix compilation on MinGW GCC 12

---
 externals/CMakeLists.txt               | 5 +++++
 src/core/loader/nso.cpp                | 9 ++++-----
 src/video_core/macro/macro_jit_x64.cpp | 2 +-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index 64361de5f..bd01f4c4d 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -40,6 +40,11 @@ target_include_directories(mbedtls PUBLIC ./mbedtls/include)
 add_library(microprofile INTERFACE)
 target_include_directories(microprofile INTERFACE ./microprofile)
 
+# GCC bugs
+if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND MINGW)
+    target_compile_options(microprofile INTERFACE "-Wno-array-bounds")
+endif()
+
 # libusb
 if (NOT LIBUSB_FOUND OR YUZU_USE_BUNDLED_LIBUSB)
     add_subdirectory(libusb)
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 8a938aa83..8dd956fc6 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -128,11 +128,10 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::
 
     // Apply patches if necessary
     if (pm && (pm->HasNSOPatch(nso_header.build_id) || Settings::values.dump_nso)) {
-        std::vector<u8> pi_header;
-        pi_header.insert(pi_header.begin(), reinterpret_cast<u8*>(&nso_header),
-                         reinterpret_cast<u8*>(&nso_header) + sizeof(NSOHeader));
-        pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(),
-                         program_image.data() + program_image.size());
+        std::vector<u8> pi_header(sizeof(NSOHeader) + program_image.size());
+        std::memcpy(pi_header.data(), &nso_header, sizeof(NSOHeader));
+        std::memcpy(pi_header.data() + sizeof(NSOHeader), program_image.data(),
+                    program_image.size());
 
         pi_header = pm->PatchNSO(pi_header, nso_file.GetName());
 
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp
index dc5376501..aca25d902 100644
--- a/src/video_core/macro/macro_jit_x64.cpp
+++ b/src/video_core/macro/macro_jit_x64.cpp
@@ -411,7 +411,7 @@ void MacroJITx64Impl::Compile_Branch(Macro::Opcode opcode) {
 
     Xbyak::Label end;
     auto value = Compile_GetRegister(opcode.src_a, eax);
-    test(value, value);
+    cmp(value, 0); // test(value, value);
     if (optimizer.has_delayed_pc) {
         switch (opcode.branch_condition) {
         case Macro::BranchCondition::Zero:

From feaf010fa2c2952eaa6659ea2decaaa2493d4bb8 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 12 Jun 2022 18:11:02 -0400
Subject: [PATCH 8/9] common/assert: rework ASSERT handling to avoid
 std::function usage

---
 src/common/assert.cpp | 10 +++-------
 src/common/assert.h   | 45 ++++++++++++++++---------------------------
 2 files changed, 20 insertions(+), 35 deletions(-)

diff --git a/src/common/assert.cpp b/src/common/assert.cpp
index 1a85faccf..6026b7dc2 100644
--- a/src/common/assert.cpp
+++ b/src/common/assert.cpp
@@ -6,13 +6,9 @@
 
 #include "common/settings.h"
 
-void assert_check_condition(bool cond, std::function<void()>&& on_failure) {
-    if (!cond) [[unlikely]] {
-        on_failure();
-
-        if (Settings::values.use_debug_asserts) {
-            Crash();
-        }
+void assert_fail_impl() {
+    if (Settings::values.use_debug_asserts) {
+        Crash();
     }
 }
 
diff --git a/src/common/assert.h b/src/common/assert.h
index fb7808657..8c927fcc0 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -4,47 +4,36 @@
 
 #pragma once
 
-#include <functional>
-
 #include "common/logging/log.h"
 
 // Sometimes we want to try to continue even after hitting an assert.
 // However touching this file yields a global recompilation as this header is included almost
 // everywhere. So let's just move the handling of the failed assert to a single cpp file.
 
-// For asserts we'd like to keep all the junk executed when an assert happens away from the
-// important code in the function. One way of doing this is to put all the relevant code inside a
-// lambda and force the compiler to not inline it.
-void assert_check_condition(bool cond, std::function<void()>&& on_failure);
-
+void assert_fail_impl();
 [[noreturn]] void unreachable_impl();
 
+#ifdef _MSC_VER
+#define YUZU_NO_INLINE __declspec(noinline)
+#else
+#define YUZU_NO_INLINE __attribute__((noinline))
+#endif
+
 #define ASSERT(_a_)                                                                                \
-    do {                                                                                           \
-        if (std::is_constant_evaluated()) {                                                        \
-            if (!(_a_)) {                                                                          \
-                /* Will trigger compile error here */                                              \
-                assert_check_condition(bool(_a_),                                                  \
-                                       [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });          \
-            }                                                                                      \
-        } else {                                                                                   \
-            assert_check_condition(bool(_a_), [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });   \
+    ([&]() YUZU_NO_INLINE {                                                                        \
+        if (!(_a_)) [[unlikely]] {                                                                 \
+            LOG_CRITICAL(Debug, "Assertion Failed!");                                              \
+            assert_fail_impl();                                                                    \
         }                                                                                          \
-    } while (0)
+    }())
 
 #define ASSERT_MSG(_a_, ...)                                                                       \
-    do {                                                                                           \
-        if (std::is_constant_evaluated()) {                                                        \
-            if (!(_a_)) {                                                                          \
-                /* Will trigger compile error here */                                              \
-                assert_check_condition(bool(_a_),                                                  \
-                                       [] { LOG_CRITICAL(Debug, "Assertion Failed!"); });          \
-            }                                                                                      \
-        } else {                                                                                   \
-            assert_check_condition(                                                                \
-                bool(_a_), [&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); });       \
+    ([&]() YUZU_NO_INLINE {                                                                        \
+        if (!(_a_)) [[unlikely]] {                                                                 \
+            LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__);                                \
+            assert_fail_impl();                                                                    \
         }                                                                                          \
-    } while (0)
+    }())
 
 #define UNREACHABLE()                                                                              \
     do {                                                                                           \

From bd38aefc573e5e554386217546bd3a0dd78cc449 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 12 Jun 2022 19:31:22 -0400
Subject: [PATCH 9/9] kernel: fix passthrough of local captures in lambda

---
 src/core/hle/kernel/kernel.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7eb961912..b2c4f12b4 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -212,7 +212,9 @@ struct KernelCore::Impl {
         system_resource_limit = KResourceLimit::Create(system.Kernel());
         system_resource_limit->Initialize(&core_timing);
 
-        const auto [total_size, kernel_size] = memory_layout->GetTotalAndKernelMemorySizes();
+        const auto sizes{memory_layout->GetTotalAndKernelMemorySizes()};
+        const auto total_size{sizes.first};
+        const auto kernel_size{sizes.second};
 
         // If setting the default system values fails, then something seriously wrong has occurred.
         ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)