forked from OSchip/llvm-project
parent
237f349073
commit
cafa0a9746
|
@ -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();
|
||||
return false;
|
||||
if (lproto && rproto == 0)
|
||||
return false;
|
||||
return !mergeTypes(lhs, rhs).isNull();
|
||||
}
|
||||
|
||||
/// areCompatVectorTypes - Return true if the two specified vector types are
|
||||
|
|
|
@ -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));
|
||||
|
||||
for (FunctionProtoType::arg_type_iterator i = FTy->arg_type_begin(),
|
||||
e = FTy->arg_type_end(); i != e; ++i)
|
||||
Types.push_back(*i);
|
||||
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) {
|
||||
|
|
|
@ -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 (^)()'}}
|
||||
|
|
|
@ -4,48 +4,48 @@ void donotwarn();
|
|||
int (^IFP) ();
|
||||
int (^II) (int);
|
||||
int test1() {
|
||||
int (^PFR) (int) = 0; // OK
|
||||
PFR = II; // OK
|
||||
int (^PFR) (int) = 0; // OK
|
||||
PFR = II; // OK
|
||||
|
||||
if (PFR == II) // OK
|
||||
donotwarn();
|
||||
if (PFR == II) // OK
|
||||
donotwarn();
|
||||
|
||||
if (PFR == IFP) // expected-error {{comparison of distinct block types}}
|
||||
donotwarn();
|
||||
if (PFR == IFP) // expected-error {{comparison of distinct block types}}
|
||||
donotwarn();
|
||||
|
||||
if (PFR == (int (^) (int))IFP) // OK
|
||||
donotwarn();
|
||||
if (PFR == (int (^) (int))IFP) // OK
|
||||
donotwarn();
|
||||
|
||||
if (PFR == 0) // OK
|
||||
donotwarn();
|
||||
if (PFR == 0) // OK
|
||||
donotwarn();
|
||||
|
||||
if (PFR) // OK
|
||||
donotwarn();
|
||||
if (PFR) // OK
|
||||
donotwarn();
|
||||
|
||||
if (!PFR) // OK
|
||||
donotwarn();
|
||||
if (!PFR) // OK
|
||||
donotwarn();
|
||||
|
||||
return PFR != IFP; // expected-error {{comparison of distinct block types}}
|
||||
return PFR != IFP; // expected-error {{comparison of distinct block types}}
|
||||
}
|
||||
|
||||
int test2(double (^S)()) {
|
||||
double (^I)(int) = (void*) S;
|
||||
(void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
|
||||
double (^I)(int) = (void*) S;
|
||||
(void*)I = (void *)S; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
|
||||
|
||||
void *pv = I;
|
||||
void *pv = I;
|
||||
|
||||
pv = S;
|
||||
pv = S;
|
||||
|
||||
I(1);
|
||||
|
||||
return (void*)I == (void *)S;
|
||||
I(1);
|
||||
|
||||
return (void*)I == (void *)S;
|
||||
}
|
||||
|
||||
int^ x; // expected-error {{block pointer to non-function type is invalid}}
|
||||
int^^ x1; // expected-error {{block pointer to non-function type is invalid}} expected-error {{block pointer to non-function type is invalid}}
|
||||
|
||||
int test3() {
|
||||
char *^ y; // expected-error {{block pointer to non-function type is invalid}}
|
||||
char *^ y; // expected-error {{block pointer to non-function type is invalid}}
|
||||
}
|
||||
|
||||
|
||||
|
@ -72,8 +72,13 @@ void test5() {
|
|||
|
||||
// rdar://6405429 - __func__ in a block refers to the containing function name.
|
||||
const char*test6() {
|
||||
return ^{
|
||||
return __func__;
|
||||
} ();
|
||||
return ^{
|
||||
return __func__;
|
||||
} ();
|
||||
}
|
||||
|
||||
// radr://6732116 - block comparisons
|
||||
void (^g)();
|
||||
int foo(void (^p)()) {
|
||||
return g == p;
|
||||
}
|
||||
|
|
|
@ -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) { }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue