summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chisnall <github@theravensnest.org>2020-12-01 09:48:25 +0000
committerTom Stellard <tstellar@redhat.com>2020-12-03 19:01:07 -0800
commitbb852a09ae36eec895445aee102d1751af9633d7 (patch)
tree17bf6a26d519d408f73a35160eb58fb93ba98f32
parent2cf5c80ab6d4635932e4e7ef84951819540bf1a8 (diff)
downloadllvm-bb852a09ae36eec895445aee102d1751af9633d7.tar.gz
[GNU ObjC] Fix a regression listing methods twice.
Methods synthesized from declared properties were being added to the method lists twice. This came from the change to list them in the class's method list, which missed removing the place in CGObjCGNU that added them again. Reviewed By: lanza Differential Revision: https://reviews.llvm.org/D91874 (cherry picked from commit d1ed67037de6f3f44dc446784f74f0e02adec9b5)
-rw-r--r--clang/lib/CodeGen/CGObjCGNU.cpp13
-rw-r--r--clang/test/CodeGenObjC/gnu-method-only-once.m23
2 files changed, 23 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp
index bb9c494ae68e..c64faf4c0af7 100644
--- a/clang/lib/CodeGen/CGObjCGNU.cpp
+++ b/clang/lib/CodeGen/CGObjCGNU.cpp
@@ -3511,19 +3511,6 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
ClassMethods.insert(ClassMethods.begin(), OID->classmeth_begin(),
OID->classmeth_end());
- // Collect the same information about synthesized properties, which don't
- // show up in the instance method lists.
- for (auto *propertyImpl : OID->property_impls())
- if (propertyImpl->getPropertyImplementation() ==
- ObjCPropertyImplDecl::Synthesize) {
- auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) {
- if (accessor)
- InstanceMethods.push_back(accessor);
- };
- addPropertyMethod(propertyImpl->getGetterMethodDecl());
- addPropertyMethod(propertyImpl->getSetterMethodDecl());
- }
-
llvm::Constant *Properties = GeneratePropertyList(OID, ClassDecl);
// Collect the names of referenced protocols
diff --git a/clang/test/CodeGenObjC/gnu-method-only-once.m b/clang/test/CodeGenObjC/gnu-method-only-once.m
new file mode 100644
index 000000000000..67d873ccc0aa
--- /dev/null
+++ b/clang/test/CodeGenObjC/gnu-method-only-once.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s -check-prefix=CHECK-NEW
+// RUN: %clang_cc1 -triple x86_64-unknown-freebsd -S -emit-llvm -fobjc-runtime=gnustep-1.8 -o - %s | FileCheck %s -check-prefix=CHECK-OLD
+
+// Clang 9 or 10 changed the handling of method lists so that methods provided
+// from synthesised properties showed up in the method list, where previously
+// CGObjCGNU had to collect them and merge them. One of the places where this
+// merging happened was missed in the move and so we ended up emitting two
+// copies of method metadata for declared properties.
+
+// This class has only instance properties and only one pair of synthesized
+// methods from the property and so we should synthesize only one method list,
+// with precisely two methods on it.
+@interface X
+@property (retain) id iProp;
+@end
+
+@implementation X
+@synthesize iProp;
+@end
+
+// Check that the method list has precisely 2 methods.
+// CHECK-NEW: @.objc_method_list = internal global { i8*, i32, i64, [2 x
+// CHECK-OLD: @.objc_method_list = internal global { i8*, i32, [2 x