[cfe-commits] r66033 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.def lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp test/SemaObjC/call-super-2.m test/SemaObjC/conditional-expr.m test/SemaObjC/property-category-1.m test/SemaObjC/property-noprotocol-warning.m
Steve Naroff
snaroff at apple.com
Wed Mar 4 07:11:51 PST 2009
Author: snaroff
Date: Wed Mar 4 09:11:40 2009
New Revision: 66033
URL: http://llvm.org/viewvc/llvm-project?rev=66033&view=rev
Log:
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'.
Added:
cfe/trunk/test/SemaObjC/call-super-2.m
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/conditional-expr.m
cfe/trunk/test/SemaObjC/property-category-1.m
cfe/trunk/test/SemaObjC/property-noprotocol-warning.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.def Wed Mar 4 09:11:40 2009
@@ -966,6 +966,8 @@
"@catch parameter is not an Objective-C class type")
DIAG(err_illegal_qualifiers_on_catch_parm, ERROR,
"illegal qualifiers on @catch parameter")
+DIAG(err_illegal_super_cast, ERROR,
+ "cannot cast 'super' (it isn't an expression)")
// C++ casts
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Mar 4 09:11:40 2009
@@ -226,6 +226,9 @@
/// extremely uncommon (only 1% of selectors are "overloaded").
llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool;
llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;
+
+ /// Private Helper predicate to check for 'self'.
+ bool isSelfExpr(Expr *RExpr);
public:
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer);
~Sema() {
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Mar 4 09:11:40 2009
@@ -2302,6 +2302,8 @@
} else if (castType->isVectorType()) {
if (CheckVectorCast(TyR, castType, castExpr->getType()))
return true;
+ } else if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) {
+ return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast);
}
return false;
}
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Mar 4 09:11:40 2009
@@ -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))
Added: cfe/trunk/test/SemaObjC/call-super-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/call-super-2.m?rev=66033&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/call-super-2.m (added)
+++ cfe/trunk/test/SemaObjC/call-super-2.m Wed Mar 4 09:11:40 2009
@@ -0,0 +1,98 @@
+// RUN: clang -fsyntax-only -verify %s
+
+#include <stddef.h>
+
+typedef struct objc_object *id;
+id objc_getClass(const char *s);
+
+ at interface Object
+ at end
+
+ at protocol Func
++ (int) class_func0;
+- (int) instance_func0;
+ at end
+
+ at interface Derived: Object
++ (int) class_func1;
++ (int) class_func2;
++ (int) class_func3;
++ (int) class_func4;
++ (int) class_func5;
++ (int) class_func6;
++ (int) class_func7;
+- (int) instance_func1;
+- (int) instance_func2;
+- (int) instance_func3;
+- (int) instance_func4;
+- (int) instance_func5;
+- (int) instance_func6;
+- (int) instance_func7;
+ at end
+
+ at implementation Derived
++ (int) class_func1
+{
+ int i = (size_t)[self class_func0]; // expected-warning {{method '-class_func0' not found (return type defaults to 'id')}}
+ return i + (size_t)[super class_func0]; // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+}
++ (int) class_func2
+{
+ int i = [(id <Func>)self class_func0]; // expected-warning {{method '-class_func0' not found (return type defaults to 'id')}} // expected-warning {{incompatible pointer to integer conversion initializing 'id', expected 'int'}}
+ i += [(id <Func>)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+ i += [(Class <Func>)self class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}}
+ return i + [(Class <Func>)super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
++ (int) class_func3
+{
+ return [(Object <Func> *)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
++ (int) class_func4
+{
+ return [(Derived <Func> *)super class_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
++ (int) class_func5
+{
+ int i = (size_t)[Derived class_func0]; // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+ return i + (size_t)[Object class_func0]; // expected-warning {{method '+class_func0' not found (return type defaults to 'id')}}
+}
++ (int) class_func6
+{
+ return (size_t)[objc_getClass("Object") class_func1]; // GCC warns about this
+}
++ (int) class_func7
+{
+ return [objc_getClass("Derived") class_func1];
+}
+- (int) instance_func1
+{
+ int i = (size_t)[self instance_func0]; // expected-warning {{method '-instance_func0' not found (return type defaults to 'id'))}}
+ return i + (size_t)[super instance_func0]; // expected-warning {{method '-instance_func0' not found (return type defaults to 'id')}}
+}
+- (int) instance_func2
+{
+ return [(id <Func>)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
+- (int) instance_func3
+{
+ return [(Object <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
+- (int) instance_func4
+{
+ return [(Derived <Func> *)super instance_func0]; // expected-error {{cannot cast 'super' (it isn't an expression)}}
+}
+- (int) instance_func5
+{
+ int i = (size_t)[Derived instance_func1]; // GCC currently warns.
+ return i + (size_t)[Object instance_func1]; // expected-warning {{method '+instance_func1' not found (return type defaults to 'id')}}
+}
+- (int) instance_func6
+{
+ return (size_t)[objc_getClass("Object") class_func1];
+}
+- (int) instance_func7
+{
+ return [objc_getClass("Derived") class_func1];
+}
+ at end
+
Modified: cfe/trunk/test/SemaObjC/conditional-expr.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/conditional-expr.m?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/conditional-expr.m (original)
+++ cfe/trunk/test/SemaObjC/conditional-expr.m Wed Mar 4 09:11:40 2009
@@ -36,7 +36,7 @@
// No @interface declaration for DTFilterOutputStream3
@implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}}
- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
- id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{DTFilterOutputStream3 may not respond to 'nextOutputStream'}}
+ id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}}
// GCC warns about both of these as well (no errors).
self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}}
return nextOutputStream ? nextOutputStream : self;
Modified: cfe/trunk/test/SemaObjC/property-category-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-category-1.m?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-category-1.m (original)
+++ cfe/trunk/test/SemaObjC/property-category-1.m Wed Mar 4 09:11:40 2009
@@ -1,7 +1,7 @@
// RUN: clang -fsyntax-only -verify %s
@interface Object
-- (id)new;
++ (id)new;
@end
@interface ReadOnly : Object
Modified: cfe/trunk/test/SemaObjC/property-noprotocol-warning.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-noprotocol-warning.m?rev=66033&r1=66032&r2=66033&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-noprotocol-warning.m (original)
+++ cfe/trunk/test/SemaObjC/property-noprotocol-warning.m Wed Mar 4 09:11:40 2009
@@ -2,7 +2,7 @@
@interface Object
-- (id) new;
++ (id) new;
@end
@protocol GCObject
More information about the cfe-commits
mailing list