[clang] [Clang] Turn isSynthesizedAccessorStub() into checks from assertions (PR #210142)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 17 09:22:05 PDT 2026


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/210142

>From 222e4ddbfb4c4027bee766278e799dada2857bad Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 16 Jul 2026 15:06:22 -0400
Subject: [PATCH] Turn isSynthesizedAccessorStub() into checks from assertions

Turns out it was crashing on real code.

If the user writes two getter methods in the @implementation (which is invalid code), Clang will process the first one (replacing the stub) and then try to process the second one. On the second one, the getter is no longer a stub, breaking the invariant and causing the crash.

Resolves: #210129
---
 clang/lib/Sema/SemaDeclObjC.cpp                 |  8 ++++----
 .../SemaObjC/property-duplicate-method-crash.m  | 17 +++++++++++++++++
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/SemaObjC/property-duplicate-method-crash.m

diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 04ba528098af4..4cedf2fa8750f 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -4875,14 +4875,14 @@ Decl *SemaObjC::ActOnMethodDeclaration(
       if (auto *Setter = PropertyImpl->getSetterMethodDecl())
         if (Setter->getSelector() == Sel &&
             Setter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
-          assert(Setter->isSynthesizedAccessorStub() && "autosynth stub expected");
-          PropertyImpl->setSetterMethodDecl(ObjCMethod);
+          if (Setter->isSynthesizedAccessorStub())
+            PropertyImpl->setSetterMethodDecl(ObjCMethod);
         }
       if (auto *Getter = PropertyImpl->getGetterMethodDecl())
         if (Getter->getSelector() == Sel &&
             Getter->isInstanceMethod() == ObjCMethod->isInstanceMethod()) {
-          assert(Getter->isSynthesizedAccessorStub() && "autosynth stub expected");
-          PropertyImpl->setGetterMethodDecl(ObjCMethod);
+          if (Getter->isSynthesizedAccessorStub())
+            PropertyImpl->setGetterMethodDecl(ObjCMethod);
           break;
         }
     }
diff --git a/clang/test/SemaObjC/property-duplicate-method-crash.m b/clang/test/SemaObjC/property-duplicate-method-crash.m
new file mode 100644
index 0000000000000..a4621db59c534
--- /dev/null
+++ b/clang/test/SemaObjC/property-duplicate-method-crash.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -Wno-objc-property-no-attribute %s
+
+ at interface I
+ at property (atomic) id atomic_prop; // expected-note {{property declared here}}
+ at end
+
+ at implementation I // expected-note {{implementation started here}}
+ at synthesize atomic_prop, atomic_prop1; // expected-error {{property implementation must have its declaration in interface 'I' or one of its extensions}}
+
+- (id) atomic_prop { return 0; } // expected-note {{previous declaration is here}} \
+                                 // expected-warning {{writable atomic property 'atomic_prop' cannot pair a synthesized setter with a user defined getter}} \
+                                 // expected-note {{setter and getter must both be synthesized, or both be user defined, or the property must be nonatomic}}
+
+- (id) atomic_prop; // expected-error {{duplicate declaration of method 'atomic_prop'}}
+
+ at end // expected-error {{expected method body}} \
+     // expected-error at 17 {{missing '@end'}}



More information about the cfe-commits mailing list