]> granicus.if.org Git - clang/commitdiff
Implemented type checking for pointer of objects of protocol-qualified types.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 12 Dec 2007 01:00:23 +0000 (01:00 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 12 Dec 2007 01:00:23 +0000 (01:00 +0000)
Note that incompatible-protocol-qualified-types.m is currently failing. This is
unrelated to this patch and Steve is looking at the general problem of not reporting
incompitible pointer types in return stetement..

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44897 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
include/clang/AST/ASTContext.h
test/Sema/incompatible-protocol-qualified-types.m [new file with mode: 0644]

index e8ed9a209fbaea1dfa4870fb5aea1996ca92f59f..4a40f839f0901a127ea6698dd4926b6d1d02cae0 100644 (file)
@@ -1168,6 +1168,34 @@ bool ASTContext::interfaceTypesAreCompatible(QualType lhs, QualType rhs) {
   return true; // FIXME: IMPLEMENT.
 }
 
+bool ASTContext::QualifiedInterfaceTypesAreCompatible(QualType lhs, 
+                                                      QualType rhs) {
+  ObjcQualifiedInterfaceType *lhsQI = 
+    dyn_cast<ObjcQualifiedInterfaceType>(lhs.getCanonicalType().getTypePtr());
+  assert(lhsQI && "QualifiedInterfaceTypesAreCompatible - bad lhs type");
+  ObjcQualifiedInterfaceType *rhsQI = 
+    dyn_cast<ObjcQualifiedInterfaceType>(rhs.getCanonicalType().getTypePtr());
+  assert(rhsQI && "QualifiedInterfaceTypesAreCompatible - bad rhs type");
+  if (!interfaceTypesAreCompatible(QualType(lhsQI->getInterfaceType(), 0), 
+                                  QualType(rhsQI->getInterfaceType(), 0)))
+    return false;
+  /* All protocols in lhs must have a presense in rhs. */
+  for (unsigned i =0; i < lhsQI->getNumProtocols(); i++) {
+    bool match = false;
+    ObjcProtocolDecl *lhsProto = lhsQI->getProtocols(i);
+    for (unsigned j = 0; j < rhsQI->getNumProtocols(); j++) {
+      ObjcProtocolDecl *rhsProto = rhsQI->getProtocols(j);
+      if (lhsProto == rhsProto) {
+        match = true;
+        break;
+      }
+    }
+    if (!match)
+      return false;
+  }
+  return true;
+}
+
 bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
   const VectorType *lVector = lhs->getAsVectorType();
   const VectorType *rVector = rhs->getAsVectorType();
@@ -1331,6 +1359,8 @@ bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
     case Type::Vector:
     case Type::OCUVector:
       return vectorTypesAreCompatible(lcanon, rcanon);
+    case Type::ObjcQualifiedInterface:
+      return QualifiedInterfaceTypesAreCompatible(lcanon, rcanon);
     default:
       assert(0 && "unexpected type");
   }
index 7170f4572bdd828872d48b004ccdfe4d10ad7c00..f77895074bb776ac1cc37456ae37ea8785aa9a09 100644 (file)
@@ -284,6 +284,7 @@ public:
   
   /// Objective-C specific type checking.
   bool interfaceTypesAreCompatible(QualType, QualType);
+  bool QualifiedInterfaceTypesAreCompatible(QualType, QualType);
   bool objcTypesAreCompatible(QualType, QualType);
   bool isObjcIdType(QualType T) const {
     if (!IdStructType) // ObjC isn't enabled
diff --git a/test/Sema/incompatible-protocol-qualified-types.m b/test/Sema/incompatible-protocol-qualified-types.m
new file mode 100644 (file)
index 0000000..0594eb7
--- /dev/null
@@ -0,0 +1,40 @@
+// RUN: clang -fsyntax-only -verify %s
+
+@protocol MyProto1 
+@end
+
+@protocol MyProto2 
+@end
+
+@interface INTF @end
+
+INTF <MyProto1> * Func(INTF <MyProto1, MyProto2> *p2)
+{
+       return p2;
+}
+
+
+INTF <MyProto1> * Func1(INTF <MyProto1, MyProto2> *p2)
+{
+       return p2;
+}
+
+INTF <MyProto1, MyProto2> * Func2(INTF <MyProto1> *p2)
+{
+       Func(p2);       // expected-warning {{incompatible pointer types passing}}
+       return p2;      // expected-warning {{incompatible pointer types passing}}
+}
+
+
+
+INTF <MyProto1> * Func3(INTF <MyProto2> *p2)
+{
+       return p2;      // expected-warning {{incompatible pointer types passing}}
+}
+
+
+INTF <MyProto1, MyProto2> * Func4(INTF <MyProto2, MyProto1> *p2)
+{
+       return p2;
+}
+