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

This lets us distinguish crashes due to different hardening checks.

PiperOrigin-RevId: 910658969
Change-Id: I820eb5291d7ce8330df0dac10ea09fafef405bbb
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index d5e01f3..6371298 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -20,6 +20,7 @@
   "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 6ade148..98772b1 100644
--- a/absl/base/BUILD.bazel
+++ b/absl/base/BUILD.bazel
@@ -63,6 +63,9 @@
 
 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 9608061..582b14c 100644
--- a/absl/base/CMakeLists.txt
+++ b/absl/base/CMakeLists.txt
@@ -46,6 +46,8 @@
     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
new file mode 100644
index 0000000..2844eec
--- /dev/null
+++ b/absl/base/internal/hardening.cc
@@ -0,0 +1,46 @@
+//
+// 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 31b25d9..6ea2833 100644
--- a/absl/base/internal/hardening.h
+++ b/absl/base/internal/hardening.h
@@ -23,15 +23,26 @@
 #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.
 //
@@ -45,7 +56,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -59,7 +70,7 @@
   ABSL_ASSERT(cond);
 #if (ABSL_OPTION_HARDENED == 1) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(!cond)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -69,7 +80,7 @@
   ABSL_ASSERT(val1 > val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 > val2)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -79,7 +90,7 @@
   ABSL_ASSERT(val1 >= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 >= val2)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -89,7 +100,7 @@
   ABSL_ASSERT(val1 < val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 < val2)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -99,7 +110,7 @@
   ABSL_ASSERT(val1 <= val2);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (!ABSL_PREDICT_TRUE(val1 <= val2)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -113,7 +124,7 @@
   ABSL_ASSERT(!container.empty());
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(container.empty())) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -123,7 +134,7 @@
   ABSL_ASSERT(ptr != nullptr);
 #if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
   if (ABSL_PREDICT_FALSE(ptr == nullptr)) {
-    base_internal::HardeningAbort();
+    ABSL_INTERNAL_ATTRIBUTE_NO_MERGE HardeningAbort();
   }
 #endif
 }
@@ -133,4 +144,6 @@
 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 d77a83c..392b7b8 100644
--- a/absl/base/macros.h
+++ b/absl/base/macros.h
@@ -53,19 +53,6 @@
 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
 
@@ -135,7 +122,8 @@
 // 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() absl::base_internal::HardeningAbort()
+#define ABSL_INTERNAL_HARDENING_ABORT() \
+  ((void)ABSL_INTERNAL_IMMEDIATE_ABORT_IMPL(), ABSL_INTERNAL_UNREACHABLE_IMPL())
 
 // ABSL_HARDENING_ASSERT()
 //
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index dde29e8..1fd32c5 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -40,14 +40,6 @@
 #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
@@ -208,8 +200,6 @@
 #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