aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-09-30 14:38:43 +0000
committerSteve Naroff <snaroff@apple.com>2008-09-30 14:38:43 +0000
commit037cda5282e73f30bb09fa316047554b1af1e2ef (patch)
tree714947b521280bafdcbe42a8e2beef39448d7830 /lib
parent33e2c5f8b568eb475a7e94d8cd557cde1768f92b (diff)
Fix <rdar://problem/6191148> [sema] Objective-C method lookup (at global scope) fails to handle overloaded selectors properly.
Long standing bug in Sema::ActOnInstanceMessage(). We now warn when messaging an "id" with multiple method signatures in scope. The diags are a little verbose, however they can be streamlined if necessary. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56843 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h4
-rw-r--r--lib/Sema/SemaDeclObjC.cpp15
-rw-r--r--lib/Sema/SemaExprObjC.cpp15
3 files changed, 28 insertions, 6 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index dcd197dad6..49d69ad92d 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -379,6 +379,10 @@ private:
/// messages sent to "id" (where the class of the object is unknown).
void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
+ /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
+ /// there are multiple signatures.
+ ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R);
+
/// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
//===--------------------------------------------------------------------===//
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index f98eeb6112..05c3bc78b3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -776,6 +776,21 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
}
}
+ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
+ SourceRange R) {
+ ObjCMethodList &MethList = InstanceMethodPool[Sel];
+
+ if (MethList.Method && MethList.Next) {
+ Diag(R.getBegin(), diag::warn_multiple_method_decl, Sel.getName(), R);
+ Diag(MethList.Method->getLocStart(), diag::warn_using_decl,
+ MethList.Method->getSourceRange());
+ for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+ Diag(Next->Method->getLocStart(), diag::warn_also_found_decl,
+ Next->Method->getSourceRange());
+ }
+ return MethList.Method;
+}
+
void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()];
if (!FirstMethod.Method) {
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index db83405283..a474b7eee7 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -283,7 +283,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// Handle messages to id.
if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
ReceiverCType->getAsBlockPointerType()) {
- ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method;
+ ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
if (!Method)
Method = FactoryMethodPool[Sel].Method;
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
@@ -306,7 +307,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
if (!Method)
Method = FactoryMethodPool[Sel].Method;
if (!Method)
- Method = InstanceMethodPool[Sel].Method;
+ Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
lbrac, rbrac, returnType))
return true;
@@ -335,9 +337,9 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// We allow sending a message to a pointer to an interface (an object).
ClassDecl = OCIReceiver->getDecl();
- // FIXME: consider using InstanceMethodPool, since it will be faster
- // than the following method (which can do *many* linear searches). The
- // idea is to add class info to InstanceMethodPool.
+ // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
+ // faster than the following method (which can do *many* linear searches).
+ // The idea is to add class info to InstanceMethodPool.
Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method) {
@@ -369,7 +371,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// behavior isn't very desirable, however we need it for GCC
// compatibility.
if (!Method)
- Method = InstanceMethodPool[Sel].Method;
+ Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
}
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
lbrac, rbrac, returnType))