summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-10-14 22:18:38 +0000
committerSteve Naroff <snaroff@apple.com>2008-10-14 22:18:38 +0000
commit8afa98916ab7bbf2a789a0f7f5c0591d43fd25b3 (patch)
tree49cabc587557a2ba2118fb69b2eca712809d4e2a /clang
parent28106756affdd568e058bb45a1009e01f6ed81e3 (diff)
downloadbcm5719-llvm-8afa98916ab7bbf2a789a0f7f5c0591d43fd25b3.tar.gz
bcm5719-llvm-8afa98916ab7bbf2a789a0f7f5c0591d43fd25b3.zip
Downgrade incompatibilities with objc qualified types (e.g. id <P>) to warnings.
Note: One day, we should consider moving the actual diags to ObjCQualifiedIdTypesAreCompatible(), since it has more information on the actual problem. GCC currently emits slightly more instructive errors for some cases involving protocols. I added a FIXME to the code. llvm-svn: 57529
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def4
-rw-r--r--clang/lib/Sema/Sema.h5
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
-rw-r--r--clang/test/SemaObjC/compatible-protocol-qualified-types.m35
-rw-r--r--clang/test/SemaObjC/comptypes-1.m4
-rw-r--r--clang/test/SemaObjC/comptypes-3.m30
-rw-r--r--clang/test/SemaObjC/comptypes-5.m4
-rw-r--r--clang/test/SemaObjC/comptypes-7.m4
-rw-r--r--clang/test/SemaObjC/conditional-expr-3.m4
-rw-r--r--clang/test/SemaObjC/conditional-expr.m4
-rw-r--r--clang/test/SemaObjC/protocol-id-test-3.m12
11 files changed, 88 insertions, 32 deletions
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
index 9cae8efaf28..fc2b7f6088e 100644
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ b/clang/include/clang/Basic/DiagnosticKinds.def
@@ -1045,6 +1045,10 @@ DIAG(err_typecheck_bool_condition, ERROR,
// 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,
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 313b9aa7016..e9e1ad15689 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -924,6 +924,11 @@ private:
/// 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
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a6197dd2b75..c8610da6bd9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1587,7 +1587,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
return IntToPointer;
if (lhsType->isIntegerType())
return PointerToInt;
- return Incompatible;
+ return IncompatibleObjCQualifiedId;
}
if (lhsType->isVectorType() || rhsType->isVectorType()) {
@@ -2034,6 +2034,13 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation loc,
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()) &&
@@ -3078,6 +3085,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
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;
diff --git a/clang/test/SemaObjC/compatible-protocol-qualified-types.m b/clang/test/SemaObjC/compatible-protocol-qualified-types.m
index 2e7eb6c43b8..583acb06562 100644
--- a/clang/test/SemaObjC/compatible-protocol-qualified-types.m
+++ b/clang/test/SemaObjC/compatible-protocol-qualified-types.m
@@ -38,3 +38,38 @@ extern NSString * const XCActiveSelectionLevel;
[[[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
diff --git a/clang/test/SemaObjC/comptypes-1.m b/clang/test/SemaObjC/comptypes-1.m
index e47bc63565f..ec0e3805211 100644
--- a/clang/test/SemaObjC/comptypes-1.m
+++ b/clang/test/SemaObjC/comptypes-1.m
@@ -42,9 +42,9 @@ int main()
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
diff --git a/clang/test/SemaObjC/comptypes-3.m b/clang/test/SemaObjC/comptypes-3.m
index 1e271c8340e..b47c9607864 100644
--- a/clang/test/SemaObjC/comptypes-3.m
+++ b/clang/test/SemaObjC/comptypes-3.m
@@ -26,24 +26,24 @@ int main()
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 */
@@ -54,11 +54,11 @@ int main()
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;
}
diff --git a/clang/test/SemaObjC/comptypes-5.m b/clang/test/SemaObjC/comptypes-5.m
index f12fa9ab5d4..9905fc4298a 100644
--- a/clang/test/SemaObjC/comptypes-5.m
+++ b/clang/test/SemaObjC/comptypes-5.m
@@ -26,8 +26,8 @@ int main()
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 */
diff --git a/clang/test/SemaObjC/comptypes-7.m b/clang/test/SemaObjC/comptypes-7.m
index ef3a7790a3d..ce0391ea07a 100644
--- a/clang/test/SemaObjC/comptypes-7.m
+++ b/clang/test/SemaObjC/comptypes-7.m
@@ -28,7 +28,7 @@ int main()
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 *'}}
@@ -42,7 +42,7 @@ int main()
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 *'}}
diff --git a/clang/test/SemaObjC/conditional-expr-3.m b/clang/test/SemaObjC/conditional-expr-3.m
index de7b828a980..f5b04339e83 100644
--- a/clang/test/SemaObjC/conditional-expr-3.m
+++ b/clang/test/SemaObjC/conditional-expr-3.m
@@ -27,11 +27,11 @@ void f1(id x, A *a) {
}
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) {
diff --git a/clang/test/SemaObjC/conditional-expr.m b/clang/test/SemaObjC/conditional-expr.m
index 2884fb4c988..c607178a57c 100644
--- a/clang/test/SemaObjC/conditional-expr.m
+++ b/clang/test/SemaObjC/conditional-expr.m
@@ -28,7 +28,7 @@
- (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
@@ -38,7 +38,7 @@
- (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
diff --git a/clang/test/SemaObjC/protocol-id-test-3.m b/clang/test/SemaObjC/protocol-id-test-3.m
index 8c2beee989c..a4be20b4a5c 100644
--- a/clang/test/SemaObjC/protocol-id-test-3.m
+++ b/clang/test/SemaObjC/protocol-id-test-3.m
@@ -29,15 +29,15 @@ id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2)
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>'}}
}
@@ -61,13 +61,13 @@ INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
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> *'}}
}
OpenPOWER on IntegriCloud