Fix block comparisons. Radar 6732116.

llvm-svn: 68171
This commit is contained in:
Mike Stump 2009-04-01 01:17:39 +00:00
parent 237f349073
commit cafa0a9746
5 changed files with 55 additions and 39 deletions

View File

@ -2701,9 +2701,9 @@ bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
const FunctionType *rbase = rhs->getAsFunctionType();
const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
if (lproto && rproto)
return !mergeTypes(lhs, rhs).isNull();
if (lproto && rproto == 0)
return false;
return !mergeTypes(lhs, rhs).isNull();
}
/// areCompatVectorTypes - Return true if the two specified vector types are

View File

@ -412,18 +412,19 @@ const llvm::Type *BlockModule::getGenericExtendedBlockLiteralType() {
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,
const BlockPointerType *BPT) {
const FunctionProtoType *FTy = cast<FunctionProtoType>(BPT->getPointeeType());
const FunctionProtoType *FTy = dyn_cast<FunctionProtoType>(BPT->getPointeeType());
const clang::QualType ResType = BPT->getPointeeType()->getAsFunctionType()->getResultType();
llvm::SmallVector<QualType, 8> Types;
Types.push_back(Ctx.getPointerType(Ctx.VoidTy));
if (FTy)
for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(),
e = FTy->arg_type_end(); i != e; ++i)
Types.push_back(*i);
return Ctx.getFunctionType(FTy->getResultType(),
&Types[0], Types.size(),
FTy->isVariadic(), 0);
return Ctx.getFunctionType(ResType, &Types[0], Types.size(),
FTy && FTy->isVariadic(), 0);
}
RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {

View File

@ -10,7 +10,7 @@ int main() {
int (^PFR) (int) = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int (^)(int)'}}
PFR = II; // OK
int (^IFP) () = PFR; // expected-warning {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)()'}}
int (^IFP) () = PFR;
const int (^CIC) () = IFP; // expected-warning {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}}

View File

@ -77,3 +77,8 @@ const char*test6() {
} ();
}
// radr://6732116 - block comparisons
void (^g)();
int foo(void (^p)()) {
return g == p;
}

View File

@ -18,9 +18,19 @@ void foo3(id (*objectCreationBlock)(int)) {
void bar4(id(^)());
void foo4(id (^objectCreationBlock)(int)) {
return bar4(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)()'}}
return bar4(objectCreationBlock);
}
void foo5(id (^x)(int)) {
void bar5(id(^)(void));
void foo5(id (^objectCreationBlock)(int)) {
return bar5(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)(void)'}}
}
void bar6(id(^)(int));
void foo6(id (^objectCreationBlock)()) {
return bar6(objectCreationBlock); // expected-warning{{incompatible block pointer types passing 'id (^)()', expected 'id (^)(int)'}}
}
void foo67(id (^x)(int)) {
if (x) { }
}