diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3130,15 +3130,21 @@ if (Chain && ID < FirstSelectorID) { // Selector already exists. Did it change? bool changed = false; - for (ObjCMethodList *M = &Data.Instance; - !changed && M && M->getMethod(); M = M->getNext()) { - if (!M->getMethod()->isFromASTFile()) + for (ObjCMethodList *M = &Data.Instance; M && M->getMethod(); + M = M->getNext()) { + if (!M->getMethod()->isFromASTFile()) { changed = true; + Data.Instance = *M; + break; + } } - for (ObjCMethodList *M = &Data.Factory; !changed && M && M->getMethod(); + for (ObjCMethodList *M = &Data.Factory; M && M->getMethod(); M = M->getNext()) { - if (!M->getMethod()->isFromASTFile()) + if (!M->getMethod()->isFromASTFile()) { changed = true; + Data.Factory = *M; + break; + } } if (!changed) continue; diff --git a/clang/test/Modules/method_pool_transitive.m b/clang/test/Modules/method_pool_transitive.m new file mode 100644 --- /dev/null +++ b/clang/test/Modules/method_pool_transitive.m @@ -0,0 +1,40 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: %clang_cc1 -Wobjc-multiple-method-names -fsyntax-only -fmodules-cache-path=%t/modules.cache -fmodules -fimplicit-module-maps -F %t/Frameworks %t/test.m -verify + +// Verify we are handling methods from transitive modules, not just from immediate ones. + +//--- Frameworks/Indirect.framework/Headers/Indirect.h +@interface NSObject +@end + +@interface Indirect : NSObject +- (int)method; +@end + +//--- Frameworks/Indirect.framework/Modules/module.modulemap +framework module Indirect { + header "Indirect.h" + export * +} + +//--- Frameworks/Immediate.framework/Headers/Immediate.h +#import +@interface Immediate : NSObject +- (void)method; +@end + +//--- Frameworks/Immediate.framework/Modules/module.modulemap +framework module Immediate { + header "Immediate.h" + export * +} + +//--- test.m +#import + +void test(id obj) { + [obj method]; // expected-warning{{multiple methods named 'method' found}} + // expected-note@Frameworks/Indirect.framework/Headers/Indirect.h:5{{using}} + // expected-note@Frameworks/Immediate.framework/Headers/Immediate.h:3{{also found}} +}