[lld] 3c787d5 - [lld-macho] Don't emit spurious dupe method warnings for +load methods
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 30 11:33:56 PDT 2023
Author: Jez Ng
Date: 2023-03-30T14:33:43-04:00
New Revision: 3c787d5a254e73a84b5013a85c199f9da0adb975
URL: https://github.com/llvm/llvm-project/commit/3c787d5a254e73a84b5013a85c199f9da0adb975
DIFF: https://github.com/llvm/llvm-project/commit/3c787d5a254e73a84b5013a85c199f9da0adb975.diff
LOG: [lld-macho] Don't emit spurious dupe method warnings for +load methods
+load methods are static initializers and treated specially by the
runtime: all +load methods for a class & its categories are called when
loading that class, unlike regular methods where only one definition
will get called per message. Thus, there is no need to check for
duplicates.
Reviewed By: #lld-macho, oontvoo
Differential Revision: https://reviews.llvm.org/D147230
Added:
Modified:
lld/MachO/ObjC.cpp
lld/test/MachO/objc-category-conflicts.s
Removed:
################################################################################
diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index dce75543fc2b..ebdfebf332cc 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -197,6 +197,19 @@ void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec,
continue;
CachedHashStringRef methodName(getReferentString(r));
+ // +load methods are special: all implementations are called by the runtime
+ // even if they are part of the same class. Thus there is no need to check
+ // for duplicates.
+ // NOTE: Instead of specifically checking for this method name, ld64 simply
+ // checks whether a class / category is present in __objc_nlclslist /
+ // __objc_nlcatlist respectively. This will be the case if the class /
+ // category has a +load method. It skips optimizing the categories if there
+ // are multiple +load methods. Since it does dupe checking as part of the
+ // optimization process, this avoids spurious dupe messages around +load,
+ // but it also means that legit dupe issues for other methods are ignored.
+ if (mKind == MK_Static && methodName.val() == "load")
+ continue;
+
auto &methodMap =
mKind == MK_Instance ? klass.instanceMethods : klass.classMethods;
if (methodMap
diff --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s
index 546f042bc067..da1b0c6b38d7 100644
--- a/lld/test/MachO/objc-category-conflicts.s
+++ b/lld/test/MachO/objc-category-conflicts.s
@@ -3,6 +3,9 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat1-with-load.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s --defsym MAKE_LOAD_METHOD=1 -o %t/cat2-with-load.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s --defsym MAKE_LOAD_METHOD=1 -o %t/klass-with-load.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass-with-no-rodata.s -o %t/klass-with-no-rodata.o
# RUN: %lld -dylib -lobjc %t/klass.o -o %t/libklass.dylib
@@ -11,24 +14,32 @@
# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/libklass.dylib %t/cat1.o \
# RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
+## Check that we don't emit spurious warnings around the +load method while
+## still emitting the other warnings. Note that we have made separate
+## `*-with-load.s` files for ease of comparison with ld64; ld64 will not warn
+## at all if multiple +load methods are present.
+# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass-with-load.o \
+# RUN: %t/cat1-with-load.o %t/cat2-with-load.o -o /dev/null 2>&1 | \
+# RUN: FileCheck %s --check-prefixes=CATCLS,CATCAT --implicit-check-not '+load'
+
## Regression test: Check that we don't crash.
# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass-with-no-rodata.o -o /dev/null
# CATCLS: warning: method '+s1' has conflicting definitions:
-# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass.o
+# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
+# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
# CATCLS: warning: method '-m1' has conflicting definitions:
-# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass.o
+# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
+# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass{{.*}}.o
# CATCAT: warning: method '+s2' has conflicting definitions:
-# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2.o
-# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
+# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
+# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
# CATCAT: warning: method '-m2' has conflicting definitions:
-# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2.o
-# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
+# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2{{.*}}.o
+# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1{{.*}}.o
#--- cat1.s
@@ -51,6 +62,11 @@
.section __DATA,__objc_catlist,regular,no_dead_strip
.quad __OBJC_$_CATEGORY_Foo_$_Cat1
+.ifdef MAKE_LOAD_METHOD
+.section __DATA,__objc_nlcatlist,regular,no_dead_strip
+ .quad __OBJC_$_CATEGORY_Foo_$_Cat1
+.endif
+
.section __DATA,__objc_const
__OBJC_$_CATEGORY_Foo_$_Cat1:
.objc_classname "Cat1"
@@ -71,7 +87,12 @@ __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1:
__OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1:
.long 24
+.ifdef MAKE_LOAD_METHOD
+ .long 3
+ .empty_objc_method "load", "v16 at 0:8", "+[Foo(Cat1) load]"
+.else
.long 2
+.endif
.empty_objc_method "s1", "v16 at 0:8", "+[Foo(Cat1) s1]"
.empty_objc_method "s2", "v16 at 0:8", "+[Foo(Cat1) s2]"
@@ -98,6 +119,11 @@ __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1:
.section __DATA,__objc_catlist,regular,no_dead_strip
.quad __OBJC_$_CATEGORY_Foo_$_Cat2
+.ifdef MAKE_LOAD_METHOD
+.section __DATA,__objc_nlcatlist,regular,no_dead_strip
+ .quad __OBJC_$_CATEGORY_Foo_$_Cat2
+.endif
+
.section __DATA,__objc_const
__OBJC_$_CATEGORY_Foo_$_Cat2:
.objc_classname "Cat2"
@@ -117,7 +143,12 @@ __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2:
__OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2:
.long 24
+.ifdef MAKE_LOAD_METHOD
+ .long 2
+ .empty_objc_method "load", "v16 at 0:8", "+[Foo(Cat2) load]"
+.else
.long 1
+.endif
.empty_objc_method "s2", "v16 at 0:8", "+[Foo(Cat2) m2]"
.section __DATA,__objc_imageinfo,regular,no_dead_strip
@@ -186,7 +217,12 @@ __OBJC_CLASS_RO_$_Foo:
__OBJC_$_CLASS_METHODS_Foo:
.long 24
+.ifdef MAKE_LOAD_METHOD
+ .long 2
+ .empty_objc_method "load", "v16 at 0:8", "+[Foo load]"
+.else
.long 1
+.endif
.empty_objc_method "s1", "v16 at 0:8", "+[Foo s1]"
__OBJC_$_INSTANCE_METHODS_Foo:
@@ -197,6 +233,11 @@ __OBJC_$_INSTANCE_METHODS_Foo:
.section __DATA,__objc_classlist,regular,no_dead_strip
.quad _OBJC_CLASS_$_Foo
+.ifdef MAKE_LOAD_METHOD
+.section __DATA,__objc_nlclslist,regular,no_dead_strip
+ .quad _OBJC_CLASS_$_Foo
+.endif
+
.section __DATA,__objc_imageinfo,regular,no_dead_strip
.long 0
.long 64
More information about the llvm-commits
mailing list