[cfe-commits] [PATCH] Treat "int (^x)()" as "int (^x)(void)" instead of a K&R style prototype
Eli Friedman
eli.friedman at gmail.com
Sun May 31 04:25:39 PDT 2009
Patch per subject; this seems like the right thing to do, considering
the spec and the comment for ASTContext::typesAreBlockCompatible.
Also, the current rules for K&R-style block pointers are simply
confusing. I'm running it by the list first to make sure this isn't
likely to break common usages of blocks.
-Eli
-------------- next part --------------
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp (revision 72663)
+++ lib/Sema/SemaType.cpp (working copy)
@@ -300,6 +300,9 @@
}
Diag(Loc, diag::warn_typecheck_function_qualifiers)
<< Result << DS.getSourceRange();
+ // Strip off the qualifiers so we don't introduce any strange behavior.
+ TypeQuals &= ~QualType::Const;
+ TypeQuals &= ~QualType::Volatile;
}
// C++ [dcl.ref]p1:
@@ -674,12 +677,17 @@
// If blocks are disabled, emit an error.
if (!LangOpts.Blocks)
Diag(DeclType.Loc, diag::err_blocks_disable);
-
- if (!T.getTypePtr()->isFunctionType())
+
+ if (!T->isFunctionType()) {
Diag(D.getIdentifierLoc(), diag::err_nonfunction_block_type);
- else
+ } else {
+ // "int (^x)()" takes zero arguments.
+ if (const FunctionNoProtoType* FNPT = T->getAsFunctionNoProtoType()) {
+ T = Context.getFunctionType(FNPT->getResultType(), 0, 0, false, 0);
+ }
T = (Context.getBlockPointerType(T)
.getQualifiedType(DeclType.Cls.TypeQuals));
+ }
break;
case DeclaratorChunk::Pointer:
// Verify that we're not building a pointer to pointer to function with
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp (revision 72663)
+++ lib/Sema/SemaExpr.cpp (working copy)
@@ -5215,7 +5215,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);
Index: test/SemaObjC/blocks.m
===================================================================
--- test/SemaObjC/blocks.m (revision 72663)
+++ test/SemaObjC/blocks.m (working copy)
@@ -18,7 +18,7 @@
void bar4(id(^)());
void foo4(id (^objectCreationBlock)(int)) {
- return bar4(objectCreationBlock);
+ return bar4(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(int)', expected 'id (^)(void)'}}
}
void bar5(id(^)(void));
@@ -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); // expected-error {{incompatible block pointer types passing 'id (^)(void)', expected 'id (^)(int)'}}
}
void foo7(id (^x)(int)) {
Index: test/Sema/block-call.c
===================================================================
--- test/Sema/block-call.c (revision 72663)
+++ test/Sema/block-call.c (working copy)
@@ -7,13 +7,13 @@
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; // expected-error {{incompatible block pointer types initializing 'int (^)(void)', expected 'int (^)(int)'}}
PFR = II; // OK
- int (^IFP) () = PFR;
+ int (^IFP) () = PFR; // expected-error {{incompatible block pointer types initializing 'int (^)(int)', expected 'int (^)(void)'}}
- const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)()', expected 'int const (^)()'}}
+ const int (^CIC) () = IFP; // expected-error {{incompatible block pointer types initializing 'int (^)(void)', expected 'int const (^)(void)'}}
const int (^CICC) () = CIC;
@@ -22,7 +22,7 @@
int * const (^IPCC1) () = IPCC;
- int * (^IPCC2) () = IPCC; // expected-error {{incompatible block pointer types initializing 'int *const (^)()', expected 'int *(^)()'}}
+ int * (^IPCC2) () = IPCC; // expected-error {{incompatible block pointer types initializing 'int *const (^)(void)', expected 'int *(^)(void)'}}
int (^IPCC3) (const int) = PFR;
@@ -35,11 +35,11 @@
int (^IPCC6) (int, char (^CArg) (float)) = IPCC4; // expected-error {{incompatible block pointer types initializing 'int (^)(int, char (^)(double))', expected 'int (^)(int, char (^)(float))'}}
IPCC2 = 0;
- IPCC2 = 1; // expected-error {{invalid conversion assigning integer 'int', expected block pointer 'int *(^)()'}}
+ IPCC2 = 1; // expected-error {{invalid conversion assigning integer 'int', expected block pointer 'int *(^)(void)'}}
int (^x)() = 0;
- int (^y)() = 3; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}}
+ int (^y)() = 3; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)(void)'}}
int a = 1;
- int (^z)() = a+4; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)()'}}
+ int (^z)() = a+4; // expected-error {{invalid conversion initializing integer 'int', expected block pointer 'int (^)(void)'}}
}
int blah() {
Index: test/Sema/block-args.c
===================================================================
--- test/Sema/block-args.c (revision 72663)
+++ test/Sema/block-args.c (working copy)
@@ -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.
}
Index: test/Sema/block-misc.c
===================================================================
--- test/Sema/block-misc.c (revision 72663)
+++ test/Sema/block-misc.c (working copy)
@@ -144,7 +144,7 @@
void (^test15f)(void);
void test15() {
- foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)()'}}
+ foo(^{ return LESS; }); // expected-error {{incompatible block pointer types passing 'int (^)(void)', expected 'long (^)(void)'}}
}
__block int test16i; // expected-error {{__block attribute not allowed, only allowed on local variables}}
@@ -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); // expected-error {{incompatible operand types ('void (^)(int)' and 'void (^)(void)')}}
(void)(bp > rp); // expected-error {{invalid operands}}
(void)(bp > 0); // expected-error {{invalid operands}}
(void)(bp > bp); // expected-error {{invalid operands}}
Index: test/CodeGen/blocks.c
===================================================================
--- test/CodeGen/blocks.c (revision 72663)
+++ test/CodeGen/blocks.c (working copy)
@@ -2,7 +2,7 @@
void (^f)(void) = ^{};
// rdar://6768379
-int f0(int (^a0)()) {
+int f0(int (^a0)(int, int, int)) {
return a0(1, 2, 3);
}
More information about the cfe-commits
mailing list