Fix binding of labels to return early if Assembler is in error state

PiperOrigin-RevId: 430962785
diff --git a/src/jit/aarch32-assembler.cc b/src/jit/aarch32-assembler.cc
index d503262..01f3bb1 100644
--- a/src/jit/aarch32-assembler.cc
+++ b/src/jit/aarch32-assembler.cc
@@ -122,6 +122,10 @@
 }
 
 void Assembler::bind(Label& l) {
+  if (error_ != Error::kNoError) {
+    return;
+  }
+
   if (l.bound) {
     error_ = Error::kLabelAlreadyBound;
     return;
diff --git a/src/jit/aarch64-assembler.cc b/src/jit/aarch64-assembler.cc
index 85e9447..af7dd7d 100644
--- a/src/jit/aarch64-assembler.cc
+++ b/src/jit/aarch64-assembler.cc
@@ -600,6 +600,10 @@
 }
 
 void Assembler::bind(Label& l) {
+  if (error_ != Error::kNoError) {
+    return;
+  }
+
   if (l.bound) {
     error_ = Error::kLabelAlreadyBound;
     return;
diff --git a/test/aarch32-assembler.cc b/test/aarch32-assembler.cc
index 3c1cbb4..2e8ae37 100644
--- a/test/aarch32-assembler.cc
+++ b/test/aarch32-assembler.cc
@@ -423,6 +423,24 @@
   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
 }
 
+TEST(AArch32Assembler, BoundOverflow) {
+  xnn_code_buffer b;
+  xnn_allocate_code_memory(&b, 4);
+  Assembler a(&b);
+  Label l1;
+  a.add(r0, r0, 2);
+  EXPECT_EQ(Error::kNoError, a.error());
+
+  // This is out of bounds, not written.
+  a.bhi(l1);
+  EXPECT_EQ(Error::kOutOfMemory, a.error());
+
+  a.bind(l1);
+  EXPECT_EQ(false, l1.bound);
+
+  ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
+}
+
 #if XNN_ARCH_ARM && XNN_PLATFORM_JIT
 TEST(AArch32Assembler, JitAllocCodeBuffer) {
   typedef uint32_t (*Func)(uint32_t);
diff --git a/test/aarch64-assembler.cc b/test/aarch64-assembler.cc
index 872f672..061611c 100644
--- a/test/aarch64-assembler.cc
+++ b/test/aarch64-assembler.cc
@@ -458,6 +458,23 @@
   ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
 }
 
+TEST(AArch64Assembler, BindOverflow) {
+  xnn_code_buffer b;
+  xnn_allocate_code_memory(&b, 4);
+  Assembler a(&b);
+  Label l1;
+  a.add(x0, x0, 2);
+  EXPECT_EQ(Error::kNoError, a.error());
+
+  // This is out of bounds, not written.
+  a.tbz(x1, 1, l1);
+  EXPECT_EQ(Error::kOutOfMemory, a.error());
+
+  a.bind(l1);
+  ASSERT_EQ(false, l1.bound);
+
+  ASSERT_EQ(xnn_status_success, xnn_release_code_memory(&b));
+}
 
 }  // namespace aarch64
 }  // namespace xnnpack