Finish up some fixes related to <rdar://problem/6497631> Message lookup is sometimes different than gcc's.
- Disallow casting 'super'. GCC allows this, however it doesn't make sense (super isn't an expression and the cast won't alter lookup/dispatch).
- Tighten up lookup when messaging 'self'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66033 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 39a89d6..8705baf 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -202,6 +202,13 @@
return anyIncompatibleArgs;
}
+bool Sema::isSelfExpr(Expr *RExpr) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RExpr))
+ if (DRE->getDecl()->getIdentifier() == &Context.Idents.get("self"))
+ return true;
+ return false;
+}
+
// Helper method for ActOnClassMethod/ActOnInstanceMethod.
// Will search "local" class/category implementations for a method decl.
// Returns 0 if no method is found.
@@ -385,6 +392,7 @@
// Handle messages to Class.
if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
ObjCMethodDecl *Method = 0;
+
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
// First check the public methods in the class interface.
@@ -396,12 +404,15 @@
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
return true;
}
- // Look for any factory method named 'Sel'.
- if (!Method)
- Method = FactoryMethodPool[Sel].Method;
- if (!Method)
- Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
+ if (!Method) {
+ // If not messaging 'self', look for any factory method named 'Sel'.
+ if (!isSelfExpr(RExpr)) {
+ Method = FactoryMethodPool[Sel].Method;
+ if (!Method)
+ Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
+ }
+ }
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
lbrac, rbrac, returnType))
return true;
@@ -462,15 +473,17 @@
}
}
}
- // If we still haven't found a method, look in the global pool. This
- // behavior isn't very desirable, however we need it for GCC
- // compatibility. FIXME: should we deviate??
- if (!Method && OCIType->qual_empty()) {
- Method = LookupInstanceMethodInGlobalPool(
- Sel, SourceRange(lbrac,rbrac));
- if (Method && !OCIType->getDecl()->isForwardDecl())
- Diag(lbrac, diag::warn_maynot_respond)
- << OCIType->getDecl()->getIdentifier()->getName() << Sel;
+ if (!isSelfExpr(RExpr)) {
+ // If we still haven't found a method, look in the global pool. This
+ // behavior isn't very desirable, however we need it for GCC
+ // compatibility. FIXME: should we deviate??
+ if (!Method && OCIType->qual_empty()) {
+ Method = LookupInstanceMethodInGlobalPool(
+ Sel, SourceRange(lbrac,rbrac));
+ if (Method && !OCIType->getDecl()->isForwardDecl())
+ Diag(lbrac, diag::warn_maynot_respond)
+ << OCIType->getDecl()->getIdentifier()->getName() << Sel;
+ }
}
}
if (Method && DiagnoseUseOfDecl(Method, receiverLoc))