diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp --- a/lld/MachO/ObjC.cpp +++ b/lld/MachO/ObjC.cpp @@ -259,12 +259,14 @@ auto getMethodsIsec = [&](const InputSection *classIsec) -> ConcatInputSection * { if (const auto *r = classIsec->getRelocAt(classLayout.roDataOffset)) { - const auto *roIsec = - cast(r->getReferentInputSection()); - if (const auto *r = roIsec->getRelocAt(roClassLayout.baseMethodsOffset)) { - if (auto *methodsIsec = - cast_or_null(r->getReferentInputSection())) - return methodsIsec; + if (const auto *roIsec = + cast_or_null(r->getReferentInputSection())) { + if (const auto *r = + roIsec->getRelocAt(roClassLayout.baseMethodsOffset)) { + if (auto *methodsIsec = cast_or_null( + r->getReferentInputSection())) + return methodsIsec; + } } } return nullptr; diff --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s --- a/lld/test/MachO/objc-category-conflicts.s +++ b/lld/test/MachO/objc-category-conflicts.s @@ -3,6 +3,7 @@ # 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/klass-with-no-rodata.s -o %t/klass-with-no-rodata.o # RUN: %lld -dylib -lobjc %t/klass.o -o %t/libklass.dylib # RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \ @@ -10,6 +11,9 @@ # 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 +## 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 @@ -199,6 +203,42 @@ .subsections_via_symbols +#--- klass-with-no-rodata.s + +.include "objc-macros.s" + +## swiftc generates some classes without a statically-linked rodata. Not +## entirely sure what the corresponding Swift inputs are required for this to +## happen; this test merely checks that we can gracefully handle this case +## without crashing. +## FIXME: It would be better if this test used the output of some real Swift +## code. + +.globl _$s11FooAACfD + +.section __DATA,__objc_data +_$s11FooAACfD: + .quad _$s11FooAACfD + .quad 0 + .quad __objc_empty_cache + .quad 0 + .quad __objc_empty_cache + +.section __DATA,__objc_catlist,regular,no_dead_strip + .quad __CATEGORY_METAFoo_$_Foo20 + +.section __DATA,__objc_const +__CATEGORY_METAFoo_$_Foo20: + .objc_classname "Foo20" + .quad _$s11FooAACfD + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .long 64 + .space 4 + #--- objc-macros.s # Macros for taking some of the boilerplate out of defining objc structs.