// assignment related diagnostics (also for argument passing, returning, etc).
DIAG(err_typecheck_convert_incompatible, ERROR,
"incompatible type %2 '%1', expected '%0'")
+DIAG(warn_incompatible_qualified_id, WARNING,
+ "incompatible type %2 '%1', expected '%0'")
+DIAG(warn_incompatible_qualified_id_operands, WARNING,
+ "invalid operands to binary expression ('%0' and '%1')")
DIAG(ext_typecheck_convert_pointer_int, EXTWARN,
"incompatible pointer to integer conversion %2 '%1', expected '%0'")
DIAG(ext_typecheck_convert_int_pointer, EXTWARN,
/// void*, we accept for now.
BlockVoidPointer,
+ /// IncompatibleObjCQualifiedId - The assignment is between a qualified
+ /// id type and something else (that is incompatible with it). For example,
+ /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
+ IncompatibleObjCQualifiedId,
+
/// Incompatible - We reject this conversion outright, it is invalid to
/// represent it in the AST.
Incompatible
return IntToPointer;
if (lhsType->isIntegerType())
return PointerToInt;
- return Incompatible;
+ return IncompatibleObjCQualifiedId;
}
if (lhsType->isVectorType() || rhsType->isVectorType()) {
if (ObjCQualifiedIdTypesAreCompatible(lType, rType, true)) {
ImpCastExprToType(rex, lType);
return Context.IntTy;
+ } else {
+ if ((lType->isObjCQualifiedIdType() && rType->isObjCQualifiedIdType())) {
+ Diag(loc, diag::warn_incompatible_qualified_id_operands,
+ lex->getType().getAsString(), rex->getType().getAsString(),
+ lex->getSourceRange(), rex->getSourceRange());
+ return QualType();
+ }
}
}
if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) &&
case BlockVoidPointer:
DiagKind = diag::ext_typecheck_convert_pointer_void_block;
break;
+ case IncompatibleObjCQualifiedId:
+ // FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
+ // it can give a more specific diagnostic.
+ DiagKind = diag::warn_incompatible_qualified_id;
+ break;
case Incompatible:
DiagKind = diag::err_typecheck_convert_incompatible;
isInvalid = true;
[[[XCActionManager defaultActionManager] selectionAtLevel:XCActiveSelectionLevel] source];
}
@end
+
+@protocol NSTextStorageDelegate;
+@class NSNotification;
+
+@interface NSTextStorage : NSObject
+
+- (void)setDelegate:(id <NSTextStorageDelegate>)delegate;
+- (id <NSTextStorageDelegate>)delegate;
+
+@end
+
+@protocol NSTextStorageDelegate <NSObject>
+@optional
+
+- (void)textStorageWillProcessEditing:(NSNotification *)notification;
+- (void)textStorageDidProcessEditing:(NSNotification *)notification;
+
+@end
+
+@interface SKTText : NSObject {
+ @private
+
+
+ NSTextStorage *_contents;
+}
+@end
+
+@implementation SKTText
+
+
+- (NSTextStorage *)contents {
+ [_contents setDelegate:self]; // expected-warning {{incompatible type sending 'SKTText *', expected 'id<NSTextStorageDelegate>'}}
+}
+
+@end
MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
(which implements MyProtocol). */
obj_p = obj; /* Ok */
- obj_p = obj_c; // expected-error {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}}
+ obj_p = obj_c; // expected-warning {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}}
obj_p = obj_cp; /* Ok */
- obj_p = obj_C; // expected-error {{incompatible type assigning 'Class', expected 'id<MyProtocol>'}}
+ obj_p = obj_C; // expected-warning {{incompatible type assigning 'Class', expected 'id<MyProtocol>'}}
/* Assigning to a 'MyOtherClass *' variable should always generate
a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
id<MyProtocolAB> obj_ab = nil;
id<MyProtocolAC> obj_ac = nil;
- obj_a = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolA>'}}
+ obj_a = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolA>'}}
obj_a = obj_ab; /* Ok */
obj_a = obj_ac; /* Ok */
- obj_b = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolB>'}}
+ obj_b = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolB>'}}
obj_b = obj_ab; /* Ok */
- obj_b = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolB>'}}
+ obj_b = obj_ac; // expected-warning {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolB>'}}
- obj_ab = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAB>'}}
- obj_ab = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAB>'}}
- obj_ab = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolAB>'}}
+ obj_ab = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAB>'}}
+ obj_ab = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAB>'}}
+ obj_ab = obj_ac; // expected-warning {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolAB>'}}
- obj_ac = obj_a; // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAC>'}}
- obj_ac = obj_b; // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}}
- obj_ac = obj_ab; // expected-error {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}}
+ obj_ac = obj_a; // expected-warning {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAC>'}}
+ obj_ac = obj_b; // expected-warning {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}}
+ obj_ac = obj_ab; // expected-warning {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}}
- if (obj_a == obj_b) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
- if (obj_b == obj_a) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
+ if (obj_a == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
+ if (obj_b == obj_a) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
if (obj_a == obj_ab) foo (); /* Ok */
if (obj_ab == obj_a) foo (); /* Ok */
if (obj_b == obj_ab) foo (); /* Ok */
if (obj_ab == obj_b) foo (); /* Ok */
- if (obj_b == obj_ac) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_b) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}}
+ if (obj_b == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolAC>')}}
+ if (obj_ac == obj_b) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolB>')}}
- if (obj_ab == obj_ac) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}}
- if (obj_ac == obj_ab) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}}
+ if (obj_ab == obj_ac) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAB>' and 'id<MyProtocolAC>')}}
+ if (obj_ac == obj_ab) foo (); // expected-warning {{invalid operands to binary expression ('id<MyProtocolAC>' and 'id<MyProtocolAB>')}}
return 0;
}
MyOtherClass<MyProtocol> *obj_c_super_p_q = nil;
MyClass<MyProtocol> *obj_c_cat_p_q = nil;
- obj_c_cat_p = obj_id_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}}
- obj_c_super_p = obj_id_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}}
+ obj_c_cat_p = obj_id_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}}
+ obj_c_super_p = obj_id_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}}
obj_id_p = obj_c_cat_p; /* Ok */
obj_id_p = obj_c_super_p; /* Ok */
obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}}
obj_p = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id<MyProtocol>'}}
- obj_p = j; // expected-error {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}}
+ obj_p = j; // expected-warning {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}}
obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}}
obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}}
i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}}
j = obj; // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}}
- j = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}}
+ j = obj_p; // expected-warning {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}}
j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}}
j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}}
}
void f2(id<P1> x) {
- id<P0> l = x; // expected-error {{incompatible type initializing 'id<P1>', expected 'id<P0>'}}
+ id<P0> l = x; // expected-warning {{incompatible type initializing 'id<P1>', expected 'id<P0>'}}
}
void f3(A *a) {
- id<P1> l = a; // expected-error {{incompatible type initializing 'A *', expected 'id<P1>'}}
+ id<P1> l = a; // expected-warning {{incompatible type initializing 'A *', expected 'id<P1>'}}
}
void f4(int cond, id x, A *a) {
- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
// GCC warns about both of these.
- self = nextOutputStream; // expected-error {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}}
+ self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream2 *'}}
return nextOutputStream ? nextOutputStream : self;
}
@end
- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream {
id <DTOutputStreams> nextOutputStream = [self nextOutputStream];
// GCC warns about both of these as well (no errors).
- self = nextOutputStream; // expected-error {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}}
+ self = nextOutputStream; // expected-warning {{incompatible type assigning 'id<DTOutputStreams>', expected 'DTFilterOutputStream3 *'}}
return nextOutputStream ? nextOutputStream : self;
}
@end
id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
{
- Func(p2); // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
- return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
+ Func(p2); // expected-warning {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
+ return p2; // expected-warning {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
}
id<MyProto1> Gunc3(id <MyProto2>p2)
{
- return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'id<MyProto1>'}}
+ return p2; // expected-warning {{incompatible type returning 'id<MyProto2>', expected 'id<MyProto1>'}}
}
INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
{
- Func(p2); // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
- return p2; // expected-error {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
+ Func(p2); // expected-warning {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
+ return p2; // expected-warning {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
}
INTF<MyProto1> * Hunc3(id <MyProto2>p2)
{
- return p2; // expected-error {{incompatible type returning 'id<MyProto2>', expected 'INTF<MyProto1> *'}}
+ return p2; // expected-warning {{incompatible type returning 'id<MyProto2>', expected 'INTF<MyProto1> *'}}
}