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 llvm-svn: 140729
This commit is contained in:
parent
3438889dec
commit
97676979a7
|
@ -1511,6 +1511,10 @@ public:
|
|||
|
||||
QualType mergeObjCGCQualifiers(QualType, QualType);
|
||||
|
||||
bool FunctionTypesMatchOnNSConsumedAttrs(
|
||||
const FunctionProtoType *FromFunctionType,
|
||||
const FunctionProtoType *ToFunctionType);
|
||||
|
||||
void ResetObjCLayout(const ObjCContainerDecl *CD) {
|
||||
ObjCLayouts[CD] = 0;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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())
|
||||
if (LangOpts.ObjCAutoRefCount &&
|
||||
!Context.FunctionTypesMatchOnNSConsumedAttrs(FromFunctionType,
|
||||
ToFunctionType))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ConvertedType = ToType;
|
||||
return true;
|
||||
|
|
|
@ -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}}
|
Loading…
Reference in New Issue