Fix <rdar://problem/6418623> Bogus block type compatibility warning.

llvm-svn: 60842
This commit is contained in:
Steve Naroff 2008-12-10 17:49:55 +00:00
parent 9499385621
commit 68e167df8e
3 changed files with 43 additions and 2 deletions

View File

@ -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);

View File

@ -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));

View File

@ -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 (^)()'}}
}