[cfe-commits] r65231 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/Sema/SemaExpr.cpp test/SemaObjC/comptypes-legal.m

Steve Naroff snaroff at apple.com
Sat Feb 21 08:18:08 PST 2009


Author: snaroff
Date: Sat Feb 21 10:18:07 2009
New Revision: 65231

URL: http://llvm.org/viewvc/llvm-project?rev=65231&view=rev
Log:

This fixes <rdar://problem/6497650> More type mismatches issues with clang.

Move two key ObjC typechecks from Sema::CheckPointerTypesForAssignment() to ASTContext::mergeTypes().

This allows us to take advantage of the recursion in ASTContext::mergeTypes(), removing some bogus warnings.

This test case I've added includes an example where we still warn (and GCC doesn't). Need to talk with folks and decide what to do. At this point, the major bogosities should be fixed.


Added:
    cfe/trunk/test/SemaObjC/comptypes-legal.m
Modified:
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=65231&r1=65230&r2=65231&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Feb 21 10:18:07 2009
@@ -2680,6 +2680,15 @@
 
   // If the canonical type classes don't match.
   if (LHSClass != RHSClass) {
+    const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType();
+    const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType();
+
+    // ID acts sort of like void* for ObjC interfaces
+    if (LHSIface && isObjCIdStructType(RHS))
+      return LHS;
+    if (RHSIface && isObjCIdStructType(LHS))
+      return RHS;
+    
     // ID is compatible with all qualified id types.
     if (LHS->isObjCQualifiedIdType()) {
       if (const PointerType *PT = RHS->getAsPointerType()) {
@@ -2808,8 +2817,13 @@
       return LHS;
     return QualType();
   case Type::ObjCInterface:
-    // Distinct ObjC interfaces are not compatible; see canAssignObjCInterfaces
-    // for checking assignment/comparison safety
+    // Check if the interfaces are assignment compatible.
+    const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType();
+    const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType();
+    if (LHSIface && RHSIface &&
+        canAssignObjCInterfaces(LHSIface, RHSIface))
+      return LHS;
+
     return QualType();
   case Type::ObjCQualifiedId:
     // Distinct qualified id's are not compatible.

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Feb 21 10:18:07 2009
@@ -2546,20 +2546,6 @@
     assert(lhptee->isFunctionType());
     return FunctionVoidPointer;
   }
-
-  // Check for ObjC interfaces
-  const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
-  const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
-  if (LHSIface && RHSIface &&
-      Context.canAssignObjCInterfaces(LHSIface, RHSIface))
-    return ConvTy;
-
-  // ID acts sort of like void* for ObjC interfaces
-  if (LHSIface && Context.isObjCIdStructType(rhptee))
-    return ConvTy;
-  if (RHSIface && Context.isObjCIdStructType(lhptee))
-    return ConvTy;
-
   // C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
   // unqualified versions of compatible types, ...
   if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),

Added: cfe/trunk/test/SemaObjC/comptypes-legal.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/comptypes-legal.m?rev=65231&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/comptypes-legal.m (added)
+++ cfe/trunk/test/SemaObjC/comptypes-legal.m Sat Feb 21 10:18:07 2009
@@ -0,0 +1,37 @@
+// RUN: clang -fsyntax-only -verify -pedantic %s
+
+ at protocol NSObject
+ at end
+ at interface NSObject <NSObject> {
+}
+ at end
+ at interface NSString : NSObject
+ at end
+void __setRetained(id *ivar, id value, NSObject **o) {
+    *ivar = value;
+}
+static NSString *_logProcessPrefix = 0;
+void func() {
+  __setRetained(&_logProcessPrefix, _logProcessPrefix, &_logProcessPrefix);
+}
+ at implementation NSObject (ScopeAdditions)
++ (void)setObjectLogProcessPrefix:(NSString *)processPrefix {
+    __setRetained(&_logProcessPrefix, processPrefix, &_logProcessPrefix);
+}
+ at end
+
+ at class Derived;
+
+NSObject *ExternFunc (NSObject *filePath, NSObject *key);
+typedef id FuncSignature (NSObject *arg1, Derived *arg2);
+
+ at interface Derived: NSObject
++ (void)registerFunc:(FuncSignature *)function;
+ at end
+
+void foo(void)
+{
+  // GCC currently allows this (it has some fiarly new support for covariant return types and contravariant argument types).
+  // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
+  [Derived registerFunc: ExternFunc];  // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)', expected 'FuncSignature *'}}
+}





More information about the cfe-commits mailing list