Skip to content

Commit 05d377d

Browse files
committed
Make ObjCSelector's lookupDirect return a TinyPtrVector
Returning a MutableArrayRef caused us to accidentally mutate the lookup table when re-arranging decls for diagnostics.
1 parent e58ba24 commit 05d377d

File tree

3 files changed

+9
-8
lines changed

3 files changed

+9
-8
lines changed

include/swift/AST/Decl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4117,8 +4117,8 @@ class ClassDecl final : public NominalTypeDecl {
41174117
///
41184118
/// \param isInstance Whether we are looking for an instance method
41194119
/// (vs. a class method).
4120-
MutableArrayRef<AbstractFunctionDecl *> lookupDirect(ObjCSelector selector,
4121-
bool isInstance);
4120+
TinyPtrVector<AbstractFunctionDecl *> lookupDirect(ObjCSelector selector,
4121+
bool isInstance);
41224122

41234123
/// Record the presence of an @objc method with the given selector.
41244124
void recordObjCMethod(AbstractFunctionDecl *method, ObjCSelector selector);

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ void ClassDecl::createObjCMethodLookup() {
13091309
});
13101310
}
13111311

1312-
MutableArrayRef<AbstractFunctionDecl *>
1312+
TinyPtrVector<AbstractFunctionDecl *>
13131313
ClassDecl::lookupDirect(ObjCSelector selector, bool isInstance) {
13141314
if (!ObjCMethodLookup) {
13151315
createObjCMethodLookup();
@@ -1325,7 +1325,7 @@ ClassDecl::lookupDirect(ObjCSelector selector, bool isInstance) {
13251325
stored.Generation = ctx.getCurrentGeneration();
13261326
}
13271327

1328-
return { stored.Methods.begin(), stored.Methods.end() };
1328+
return stored.Methods;
13291329
}
13301330

13311331
void ClassDecl::recordObjCMethod(AbstractFunctionDecl *method,

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,7 +2073,7 @@ bool swift::diagnoseUnintendedObjCMethodOverrides(SourceFile &sf) {
20732073
}
20742074

20752075
/// Retrieve the source file for the given Objective-C member conflict.
2076-
static MutableArrayRef<AbstractFunctionDecl *>
2076+
static TinyPtrVector<AbstractFunctionDecl *>
20772077
getObjCMethodConflictDecls(const SourceFile::ObjCMethodConflict &conflict) {
20782078
ClassDecl *classDecl = std::get<0>(conflict);
20792079
ObjCSelector selector = std::get<1>(conflict);
@@ -2150,22 +2150,23 @@ bool swift::diagnoseObjCMethodConflicts(SourceFile &sf) {
21502150

21512151
// If the first method is in an extension and the second is not, swap them
21522152
// so the primary diagnostic is on the extension method.
2153+
MutableArrayRef<AbstractFunctionDecl *> methodsRef(methods);
21532154
if (isa<ExtensionDecl>(methods[0]->getDeclContext()) &&
21542155
!isa<ExtensionDecl>(methods[1]->getDeclContext())) {
2155-
std::swap(methods[0], methods[1]);
2156+
std::swap(methodsRef[0], methodsRef[1]);
21562157

21572158
// Within a source file, use our canonical ordering.
21582159
} else if (methods[0]->getParentSourceFile() ==
21592160
methods[1]->getParentSourceFile() &&
21602161
!ordering(methods[0], methods[1])) {
2161-
std::swap(methods[0], methods[1]);
2162+
std::swap(methodsRef[0], methodsRef[1]);
21622163
}
21632164

21642165
// Otherwise, fall back to the order in which the declarations were type
21652166
// checked.
21662167

21672168
auto originalMethod = methods.front();
2168-
auto conflictingMethods = methods.slice(1);
2169+
auto conflictingMethods = methodsRef.slice(1);
21692170

21702171
auto origDiagInfo = getObjCMethodDiagInfo(originalMethod);
21712172
for (auto conflictingDecl : conflictingMethods) {

0 commit comments

Comments
 (0)