Add [[clang::nomerge]] to absl::base_internal::HardeningAbort()

This lets us distinguish crashes due to different hardening checks.

PiperOrigin-RevId: 910325607
Change-Id: I902df2b849af9dcc0330315cf913d9ed63163bc1
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 6371298..d5e01f3 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -20,7 +20,6 @@
   "base/internal/dynamic_annotations.h"
   "base/internal/endian.h"
   "base/internal/errno_saver.h"
-  "base/internal/hardening.cc"
   "base/internal/hardening.h"
   "base/internal/hide_ptr.h"
   "base/internal/iterator_traits.h"
diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel
index 98772b1..6ade148 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -63,9 +63,6 @@
 
 cc_library(
     name = "hardening",
-    srcs = [
-        "internal/hardening.cc",
-    ],
     hdrs = [
         "internal/hardening.h",
     ],
diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt
index 582b14c..9608061 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -46,8 +46,6 @@
     hardening
   HDRS
     "internal/hardening.h"
-  SRCS
-    "internal/hardening.cc"
   DEPS
     absl::config
     absl::core_headers
diff --git a/absl/base/internal/hardening.cc b/absl/base/internal/hardening.cc
deleted file mode 100644
index 2844eec..0000000
--- a/absl/base/internal/hardening.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// Copyright 2026 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifdef _WIN32
-#include <intrin.h>
-// kFastFailInvalidArg mirrors the FAST_FAIL_INVALID_ARG macro.
-// Typically FAST_FAIL_INVALID_ARG would be imported from winnt.h
-// but winnt.h pulls in other dependencies and introduces build failures.
-constexpr unsigned int kFastFailInvalidArg = 5u;
-#endif
-
-#include "absl/base/internal/hardening.h"
-
-#include "absl/base/attributes.h"
-#include "absl/base/config.h"
-#include "absl/base/macros.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-namespace base_internal {
-
-[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void HardeningAbort() {
-#ifdef _WIN32
-  __fastfail(kFastFailInvalidArg);
-#else
-  ABSL_INTERNAL_HARDENING_ABORT();
-#endif
-}
-
-}  // namespace base_internal
-
-ABSL_NAMESPACE_END
-}  // namespace absl
diff --git a/absl/base/internal/hardening.h b/absl/base/internal/hardening.h
index 6ea2833..31b25d9 100644
--- a/absl/base/internal/hardening.h
+++ b/absl/base/internal/hardening.h
@@ -23,26 +23,15 @@
 #ifndef ABSL_BASE_INTERNAL_HARDENING_H_
 #define ABSL_BASE_INTERNAL_HARDENING_H_
 
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/macros.h"
 #include "absl/base/options.h"
 
-#ifdef ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-#error ABSL_INTERNAL_ATTRIBUTE_NO_MERGE cannot be directly set
-#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
-#define ABSL_INTERNAL_ATTRIBUTE_NO_MERGE [[clang::nomerge]]
-#else
-#define ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-#endif
-
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 
 namespace base_internal {
 
-[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void HardeningAbort();
-
 // `HardeningAssert` performs runtime checks when Abseil Hardening is enabled,
 // even if `NDEBUG` is defined.
 //
@@ -56,7 +45,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -70,7 +59,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -80,7 +69,7 @@
   ABSL_ASSERT(val1 > val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 > val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -90,7 +79,7 @@
   ABSL_ASSERT(val1 >= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 >= val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -100,7 +89,7 @@
   ABSL_ASSERT(val1 < val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 < val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -110,7 +99,7 @@
   ABSL_ASSERT(val1 <= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 <= val2)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -124,7 +113,7 @@
   ABSL_ASSERT(!container.empty());
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(container.empty())) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -134,7 +123,7 @@
   ABSL_ASSERT(ptr != nullptr);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(ptr == nullptr)) {
-    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
+    base_internal::HardeningAbort();
   }
 #endif
 }
@@ -144,6 +133,4 @@
 ABSL_NAMESPACE_END
 }  // namespace absl
 
-#undef ABSL_INTERNAL_ATTRIBUTE_NO_MERGE
-
 #endif  // ABSL_BASE_INTERNAL_HARDENING_H_
diff --git a/absl/base/macros.h b/absl/base/macros.h
index 392b7b8..d77a83c 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -53,6 +53,19 @@
 template <typename T, size_t N>
 auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N];
 }  // namespace macros_internal
+
+namespace base_internal {
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
+[[clang::nomerge]]  // Needed when this function is not inlined
+#endif
+[[noreturn]] inline void HardeningAbort() {
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::nomerge)
+  [[clang::nomerge]]  // Needed when this function is inlined
+#endif
+  ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL();
+  ABSL_INTERNAL_UNREACHABLE_IMPL();
+}
+}  // namespace base_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
 
@@ -122,8 +135,7 @@
 // aborts the program in release mode (when NDEBUG is defined). The
 // implementation should abort the program as quickly as possible and ideally it
 // should not be possible to ignore the abort request.
-#define ABSL_INTERNAL_HARDENING_ABORT() \
-  ((void)ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(), ABSL_INTERNAL_UNREACHABLE_IMPL())
+#define ABSL_INTERNAL_HARDENING_ABORT() absl::base_internal::HardeningAbort()
 
 // ABSL_HARDENING_ASSERT()
 //
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index 1fd32c5..dde29e8 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -40,6 +40,14 @@
 #include "absl/base/config.h"
 #include "absl/base/options.h"
 
+#ifdef _MSC_VER
+#ifdef __cplusplus
+extern "C"
+#endif
+void __cdecl __ud2(void);
+#pragma intrinsic(__ud2)
+#endif
+
 // ABSL_BLOCK_TAIL_CALL_OPTIMIZATION
 //
 // Instructs the compiler to avoid optimizing tail-call recursion. This macro is
@@ -200,6 +208,8 @@
 #if ABSL_HAVE_BUILTIN(__builtin_trap) || \
     (defined(__GNUC__) && !defined(__clang__))
 #define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() __builtin_trap()
+#elif defined(_MSC_VER)
+#define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() (__ud2(), __assume(false))
 #else
 #define ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL() abort()
 #endif