Merge "Allow nested usage of ScopedDisableMTE."
diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h
index 661664a..fbf3895 100644
--- a/libc/platform/bionic/mte.h
+++ b/libc/platform/bionic/mte.h
@@ -42,20 +42,26 @@
 }
 #endif
 
-struct ScopedDisableMTE {
-  ScopedDisableMTE() {
 #ifdef __aarch64__
+class ScopedDisableMTE {
+  size_t prev_tco_;
+
+ public:
+  ScopedDisableMTE() {
     if (mte_supported()) {
-      __asm__ __volatile__(".arch_extension mte; msr tco, #1");
+      __asm__ __volatile__(".arch_extension mte; mrs %0, tco; msr tco, #1" : "=r"(prev_tco_));
     }
-#endif
   }
 
   ~ScopedDisableMTE() {
-#ifdef __aarch64__
     if (mte_supported()) {
-      __asm__ __volatile__(".arch_extension mte; msr tco, #0");
+      __asm__ __volatile__(".arch_extension mte; msr tco, %0" : : "r"(prev_tco_));
     }
-#endif
   }
 };
+#else
+struct ScopedDisableMTE {
+  // Silence unused variable warnings in non-aarch64 builds.
+  ScopedDisableMTE() {}
+};
+#endif
diff --git a/tests/mte_test.cpp b/tests/mte_test.cpp
index 2f922a2..8928805 100644
--- a/tests/mte_test.cpp
+++ b/tests/mte_test.cpp
@@ -16,17 +16,30 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/macros.h>
 #include <bionic/mte.h>
 
 __attribute__((no_sanitize("hwaddress")))
 static void test_tag_mismatch() {
-  ScopedDisableMTE x;
-#if defined(__aarch64__)
   std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
   p[0] = 1;
-  int* mistagged_p = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p.get()) + (1ULL << 56));
-  volatile int load = *mistagged_p;
-  (void)load;
+  int* mistagged_p ATTRIBUTE_UNUSED =
+      reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(p.get()) + (1ULL << 56));
+  {
+    ScopedDisableMTE x;
+    { ScopedDisableMTE y; }
+#if defined(__aarch64__)
+    volatile int load ATTRIBUTE_UNUSED = *mistagged_p;
+#endif
+  }
+#if defined(__aarch64__)
+  if (mte_supported()) {
+    EXPECT_DEATH(
+        {
+          volatile int load ATTRIBUTE_UNUSED = *mistagged_p;
+        },
+        "");
+  }
 #endif
 }