forked from OSchip/llvm-project
Fix <rdar://problem/6418623> Bogus block type compatibility warning.
llvm-svn: 60842
This commit is contained in:
parent
9499385621
commit
68e167df8e
|
@ -1920,7 +1920,13 @@ bool ASTContext::isObjCObjectPointerType(QualType Ty) const {
|
|||
/// FIXME: When the dust settles on this integration, fold this into mergeTypes.
|
||||
///
|
||||
bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
|
||||
return getCanonicalType(lhs) == getCanonicalType(rhs);
|
||||
const FunctionType *lbase = lhs->getAsFunctionType();
|
||||
const FunctionType *rbase = rhs->getAsFunctionType();
|
||||
const FunctionTypeProto *lproto = dyn_cast<FunctionTypeProto>(lbase);
|
||||
const FunctionTypeProto *rproto = dyn_cast<FunctionTypeProto>(rbase);
|
||||
if (lproto && rproto)
|
||||
return !mergeTypes(lhs, rhs).isNull();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// areCompatVectorTypes - Return true if the two specified vector types are
|
||||
|
@ -2179,6 +2185,19 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
|
|||
return RHS;
|
||||
return getPointerType(ResultType);
|
||||
}
|
||||
case Type::BlockPointer:
|
||||
{
|
||||
// Merge two block pointer types, while trying to preserve typedef info
|
||||
QualType LHSPointee = LHS->getAsBlockPointerType()->getPointeeType();
|
||||
QualType RHSPointee = RHS->getAsBlockPointerType()->getPointeeType();
|
||||
QualType ResultType = mergeTypes(LHSPointee, RHSPointee);
|
||||
if (ResultType.isNull()) return QualType();
|
||||
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
|
||||
return LHS;
|
||||
if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
|
||||
return RHS;
|
||||
return getBlockPointerType(ResultType);
|
||||
}
|
||||
case Type::ConstantArray:
|
||||
{
|
||||
const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
|
||||
|
|
|
@ -24,7 +24,7 @@ int main() {
|
|||
|
||||
int * (^IPCC2) () = IPCC; // expected-warning {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}}
|
||||
|
||||
int (^IPCC3) (const int) = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)(int const)'}}
|
||||
int (^IPCC3) (const int) = PFR;
|
||||
|
||||
|
||||
int (^IPCC4) (int, char (^CArg) (double));
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: clang -fsyntax-only -verify -fblocks %s
|
||||
@protocol NSObject;
|
||||
|
||||
void bar(id(^)(void));
|
||||
void foo(id <NSObject>(^objectCreationBlock)(void)) {
|
||||
return bar(objectCreationBlock);
|
||||
}
|
||||
|
||||
void bar2(id(*)(void));
|
||||
void foo2(id <NSObject>(*objectCreationBlock)(void)) {
|
||||
return bar2(objectCreationBlock);
|
||||
}
|
||||
|
||||
void bar3(id(*)());
|
||||
void foo3(id (*objectCreationBlock)(int)) {
|
||||
return bar3(objectCreationBlock);
|
||||
}
|
||||
|
||||
void bar4(id(^)());
|
||||
void foo4(id (^objectCreationBlock)(int)) {
|
||||
return bar4(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)()'}}
|
||||
}
|
Loading…
Reference in New Issue