]> granicus.if.org Git - clang/commitdiff
objc arc: Diagnose block pointer type mismatch when
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Sep 2011 21:52:05 +0000 (21:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 28 Sep 2011 21:52:05 +0000 (21:52 +0000)
some arguments types are ns_consumed and some otherwise
matching types are not. This is objc side of
// rdar://10187884

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

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp
lib/Sema/SemaOverload.cpp
test/SemaObjC/arc-nsconsumed-errors.m [new file with mode: 0644]

index 458a8a44eb5120ad6a4c32116bb87c192635da00..8d2ebb31d68108261337840023af3887ae00e32c 100644 (file)
@@ -1510,6 +1510,10 @@ public:
                                      bool Unqualified = false);
   
   QualType mergeObjCGCQualifiers(QualType, QualType);
+    
+  bool FunctionTypesMatchOnNSConsumedAttrs(
+         const FunctionProtoType *FromFunctionType,
+         const FunctionProtoType *ToFunctionType);
 
   void ResetObjCLayout(const ObjCContainerDecl *CD) {
     ObjCLayouts[CD] = 0;
index 98ce45f452b6a3d6e617a927d14bfc062358ea35..4bafb2b6e72a1ce0e86017ab4d56b6d22b5740fd 100644 (file)
@@ -5570,6 +5570,10 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
     if (lproto->getTypeQuals() != rproto->getTypeQuals())
       return QualType();
 
+    if (LangOpts.ObjCAutoRefCount &&
+        !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto))
+      return QualType();
+      
     // Check argument compatibility
     SmallVector<QualType, 10> types;
     for (unsigned i = 0; i < lproto_nargs; i++) {
@@ -5594,6 +5598,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
       if (getCanonicalType(argtype) != getCanonicalType(rargtype))
         allRTypes = false;
     }
+      
     if (allLTypes) return lhs;
     if (allRTypes) return rhs;
 
@@ -5892,6 +5897,26 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
   return QualType();
 }
 
+bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs(
+                   const FunctionProtoType *FromFunctionType,
+                   const FunctionProtoType *ToFunctionType) {
+  if (FromFunctionType->hasAnyConsumedArgs() != 
+      ToFunctionType->hasAnyConsumedArgs())
+    return false;
+  FunctionProtoType::ExtProtoInfo FromEPI = 
+    FromFunctionType->getExtProtoInfo();
+  FunctionProtoType::ExtProtoInfo ToEPI = 
+    ToFunctionType->getExtProtoInfo();
+  if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments)
+    for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
+         ArgIdx != NumArgs; ++ArgIdx)  {
+      if (FromEPI.ConsumedArguments[ArgIdx] != 
+          ToEPI.ConsumedArguments[ArgIdx])
+        return false;
+    }
+  return true;
+}
+
 /// mergeObjCGCQualifiers - This routine merges ObjC's GC attribute of 'LHS' and
 /// 'RHS' attributes and returns the merged version; including for function
 /// return types.
index 63d4f5ade3fca55dde31539fbf6b4fb5eb5ae345..0c9083ef2f2850ff79f8180d3398fea4d951aec9 100644 (file)
@@ -2074,22 +2074,10 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
        // Argument types are too different. Abort.
        return false;
    }
-   if (LangOpts.ObjCAutoRefCount) {
-     if (FromFunctionType->hasAnyConsumedArgs() != 
-         ToFunctionType->hasAnyConsumedArgs())
-      return false;
-     FunctionProtoType::ExtProtoInfo FromEPI = 
-      FromFunctionType->getExtProtoInfo();
-     FunctionProtoType::ExtProtoInfo ToEPI = 
-      ToFunctionType->getExtProtoInfo();
-     if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments)
-       for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
-            ArgIdx != NumArgs; ++ArgIdx)  {
-         if (FromEPI.ConsumedArguments[ArgIdx] != 
-             ToEPI.ConsumedArguments[ArgIdx])
-           return false;
-       }
-   }
+   if (LangOpts.ObjCAutoRefCount && 
+       !Context.FunctionTypesMatchOnNSConsumedAttrs(FromFunctionType, 
+                                                    ToFunctionType))
+     return false;
    
    ConvertedType = ToType;
    return true;
diff --git a/test/SemaObjC/arc-nsconsumed-errors.m b/test/SemaObjC/arc-nsconsumed-errors.m
new file mode 100644 (file)
index 0000000..6e10fde
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fsyntax-only -fobjc-arc -verify -fblocks -triple x86_64-apple-darwin10.0.0 %s
+// rdar://10187884
+
+typedef void (^blk)(id arg1, __attribute((ns_consumed)) id arg2);
+typedef void (^blk1)(__attribute((ns_consumed))id arg1, __attribute((ns_consumed)) id arg2);
+blk a = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
+
+blk b = ^void (id arg1, __attribute((ns_consumed)) id arg2){};
+
+blk c = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
+
+blk d = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}
+
+blk1 a1 = ^void (__attribute((ns_consumed)) id arg1, id arg2){}; // expected-error {{incompatible block pointer types initializing}}
+
+blk1 b2 = ^void (id arg1, __attribute((ns_consumed)) id arg2){}; // expected-error {{incompatible block pointer types initializing}}
+
+blk1 c3 = ^void (__attribute((ns_consumed)) id arg1, __attribute((ns_consumed)) id arg2){};
+
+blk1 d4 = ^void (id arg1, id arg2) {}; // expected-error {{incompatible block pointer types initializing}}