Don't allow defining a block with a non-prototype type. Remove a
hack which introduces some strange inconsistencies in compatibility
for block pointers.
Note that unlike an earlier revision proposed on cfe-commits, this patch
still allows declaring block pointers without a prototype.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73041 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e6dea7c..5c886b8 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2853,12 +2853,6 @@
/// FIXME: When the dust settles on this integration, fold this into mergeTypes.
///
bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) {
- const FunctionType *lbase = lhs->getAsFunctionType();
- const FunctionType *rbase = rhs->getAsFunctionType();
- const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
- const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
- if (lproto && rproto == 0)
- return false;
return !mergeTypes(lhs, rhs).isNull();
}
diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp
index 9d73d90..8393574 100644
--- a/lib/Frontend/RewriteBlocks.cpp
+++ b/lib/Frontend/RewriteBlocks.cpp
@@ -1011,9 +1011,7 @@
CI != E; ++CI)
if (*CI) {
if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
- Stmt *newStmt = RewriteFunctionBody(CBE->getBody());
- if (newStmt)
- *CI = newStmt;
+ RewriteFunctionBody(CBE->getBody());
// We've just rewritten the block body in place.
// Now we snarf the rewritten text and stash it away for later use.
@@ -1023,9 +1021,7 @@
// Do the rewrite, using S.size() which contains the rewritten size.
ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
} else {
- Stmt *newStmt = RewriteFunctionBody(*CI);
- if (newStmt)
- *CI = newStmt;
+ RewriteFunctionBody(*CI);
}
}
// Handle specific things.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ee5132a..98d3a23 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5220,7 +5220,7 @@
QualType BlockTy;
if (!BSI->hasPrototype)
- BlockTy = Context.getFunctionNoProtoType(RetTy);
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0);
else
BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
BSI->isVariadic, 0);
diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c
index a2d8e5a..27bee77 100644
--- a/test/Sema/block-args.c
+++ b/test/Sema/block-args.c
@@ -18,7 +18,7 @@
^{return 1;}();
^{return 2;}(arg); // expected-error {{too many arguments to block call}}
^(void){return 3;}(1); // expected-error {{too many arguments to block call}}
- ^(){return 4;}(arg); // C style (...), ok.
+ ^(){return 4;}(arg); // expected-error {{too many arguments to block call}}
^(int x, ...){return 5;}(arg, arg); // Explicit varargs, ok.
}
diff --git a/test/Sema/block-call.c b/test/Sema/block-call.c
index 9d3ff71..c42b642 100644
--- a/test/Sema/block-call.c
+++ b/test/Sema/block-call.c
@@ -7,10 +7,10 @@
int (*FPL) (int) = FP; // C doesn't consider this an error.
// For Blocks, the ASTContext::typesAreBlockCompatible() makes sure this is an error.
- int (^PFR) (int) = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int (^)(int)'}}
+ int (^PFR) (int) = IFP; // OK
PFR = II; // OK
- int (^IFP) () = PFR;
+ int (^IFP) () = PFR; // OK
const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}}
diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c
index 93ca3c4..294c295 100644
--- a/test/Sema/block-misc.c
+++ b/test/Sema/block-misc.c
@@ -10,7 +10,7 @@
if (PFR == II) // OK
donotwarn();
- if (PFR == IFP) // expected-error {{comparison of distinct block types}}
+ if (PFR == IFP) // OK
donotwarn();
if (PFR == (int (^) (int))IFP) // OK
@@ -25,7 +25,7 @@
if (!PFR) // OK
donotwarn();
- return PFR != IFP; // expected-error {{comparison of distinct block types}}
+ return PFR != IFP; // OK
}
int test2(double (^S)()) {
@@ -165,7 +165,7 @@
f(1 ? bp : vp);
f(1 ? vp : bp);
- f(1 ? bp : bp1); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (^)()')}}
+ f(1 ? bp : bp1);
(void)(bp > rp); // expected-error {{invalid operands}}
(void)(bp > 0); // expected-error {{invalid operands}}
(void)(bp > bp); // expected-error {{invalid operands}}
diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m
index baadbde..6dab289 100644
--- a/test/SemaObjC/blocks.m
+++ b/test/SemaObjC/blocks.m
@@ -28,7 +28,7 @@
void bar6(id(^)(int));
void foo6(id (^objectCreationBlock)()) {
- return bar6(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)()', expected 'id (^)(int)'}}
+ return bar6(objectCreationBlock);
}
void foo7(id (^x)(int)) {