Author: snaroff
Date: Tue Oct 14 17:18:38 2008
New Revision: 57529

URL: http://llvm.org/viewvc/llvm-project?rev=57529&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaObjC/compatible-protocol-qualified-types.m
    cfe/trunk/test/SemaObjC/comptypes-1.m
    cfe/trunk/test/SemaObjC/comptypes-3.m
    cfe/trunk/test/SemaObjC/comptypes-5.m
    cfe/trunk/test/SemaObjC/comptypes-7.m
    cfe/trunk/test/SemaObjC/conditional-expr-3.m
    cfe/trunk/test/SemaObjC/conditional-expr.m
    cfe/trunk/test/SemaObjC/protocol-id-test-3.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Oct 14 17:18:38 2008
@@ -1045,6 +1045,10 @@
 // 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,

Modified: cfe/trunk/lib/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Oct 14 17:18:38 2008
@@ -924,6 +924,11 @@
     /// 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

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Oct 14 17:18:38 2008
@@ -1587,7 +1587,7 @@
       return IntToPointer;
     if (lhsType->isIntegerType())
       return PointerToInt;
-    return Incompatible;
+    return IncompatibleObjCQualifiedId;
   }
 
   if (lhsType->isVectorType() || rhsType->isVectorType()) {
@@ -2034,6 +2034,13 @@
     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 @@
   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;

Modified: cfe/trunk/test/SemaObjC/compatible-protocol-qualified-types.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/compatible-protocol-qualified-types.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/compatible-protocol-qualified-types.m (original)
+++ cfe/trunk/test/SemaObjC/compatible-protocol-qualified-types.m Tue Oct 14 
17:18:38 2008
@@ -38,3 +38,38 @@
     [[[XCActionManager defaultActionManager] 
selectionAtLevel:XCActiveSelectionLevel] source];
 }
 @end
+
[EMAIL PROTECTED] NSTextStorageDelegate;
[EMAIL PROTECTED] NSNotification;
+
[EMAIL PROTECTED] NSTextStorage : NSObject
+
+- (void)setDelegate:(id <NSTextStorageDelegate>)delegate;
+- (id <NSTextStorageDelegate>)delegate;
+
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] NSTextStorageDelegate <NSObject>
[EMAIL PROTECTED]
+
+- (void)textStorageWillProcessEditing:(NSNotification *)notification;
+- (void)textStorageDidProcessEditing:(NSNotification *)notification;
+
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] SKTText : NSObject {
+    @private
+
+
+    NSTextStorage *_contents;
+}
[EMAIL PROTECTED]
+
[EMAIL PROTECTED] SKTText
+
+
+- (NSTextStorage *)contents {
+ [_contents setDelegate:self]; // expected-warning {{incompatible type sending 
'SKTText *', expected 'id<NSTextStorageDelegate>'}}
+}
+
[EMAIL PROTECTED]

Modified: cfe/trunk/test/SemaObjC/comptypes-1.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-1.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-1.m (original)
+++ cfe/trunk/test/SemaObjC/comptypes-1.m Tue Oct 14 17:18:38 2008
@@ -42,9 +42,9 @@
      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

Modified: cfe/trunk/test/SemaObjC/comptypes-3.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-3.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-3.m (original)
+++ cfe/trunk/test/SemaObjC/comptypes-3.m Tue Oct 14 17:18:38 2008
@@ -26,24 +26,24 @@
   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 @@
   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;
 }

Modified: cfe/trunk/test/SemaObjC/comptypes-5.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-5.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-5.m (original)
+++ cfe/trunk/test/SemaObjC/comptypes-5.m Tue Oct 14 17:18:38 2008
@@ -26,8 +26,8 @@
   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 */
 

Modified: cfe/trunk/test/SemaObjC/comptypes-7.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-7.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-7.m (original)
+++ cfe/trunk/test/SemaObjC/comptypes-7.m Tue Oct 14 17:18:38 2008
@@ -28,7 +28,7 @@
   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 @@
   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 *'}}
   

Modified: cfe/trunk/test/SemaObjC/conditional-expr-3.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/conditional-expr-3.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/conditional-expr-3.m (original)
+++ cfe/trunk/test/SemaObjC/conditional-expr-3.m Tue Oct 14 17:18:38 2008
@@ -27,11 +27,11 @@
 }
 
 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) {

Modified: cfe/trunk/test/SemaObjC/conditional-expr.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/conditional-expr.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/conditional-expr.m (original)
+++ cfe/trunk/test/SemaObjC/conditional-expr.m Tue Oct 14 17:18:38 2008
@@ -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

Modified: cfe/trunk/test/SemaObjC/protocol-id-test-3.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-id-test-3.m?rev=57529&r1=57528&r2=57529&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-id-test-3.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-id-test-3.m Tue Oct 14 17:18:38 2008
@@ -29,15 +29,15 @@
 
 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, 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> *'}}
 }
 
 


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to