From 78213e4aec6d8d22b5828dd2687fa19116ebaa26 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 28 Sep 2011 21:52:05 +0000 Subject: [PATCH] objc arc: Diagnose block pointer type mismatch when 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 | 4 ++++ lib/AST/ASTContext.cpp | 25 +++++++++++++++++++++++++ lib/Sema/SemaOverload.cpp | 20 ++++---------------- test/SemaObjC/arc-nsconsumed-errors.m | 20 ++++++++++++++++++++ 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 test/SemaObjC/arc-nsconsumed-errors.m diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 458a8a44eb..8d2ebb31d6 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -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; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 98ce45f452..4bafb2b6e7 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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 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. diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 63d4f5ade3..0c9083ef2f 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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 index 0000000000..6e10fdeaa0 --- /dev/null +++ b/test/SemaObjC/arc-nsconsumed-errors.m @@ -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}} -- 2.50.1