summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-05-08 03:34:22 +0000
committerJohn McCall <rjmccall@apple.com>2013-05-08 03:34:22 +0000
commit1b4259b53b24d42552f1242a80b07ddf12203940 (patch)
treeae9188e00423ed8ad2e8a4d8920f5ab2720e8b8f /clang
parent220dd334468e8dbfc3b3b5d21fea24ed01a602b4 (diff)
downloadbcm5719-llvm-1b4259b53b24d42552f1242a80b07ddf12203940.tar.gz
bcm5719-llvm-1b4259b53b24d42552f1242a80b07ddf12203940.zip
In block enum-return inference, don't die on loads of enum lvalues.
More of rdar://13200889. llvm-svn: 181390
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaLambda.cpp7
-rw-r--r--clang/test/SemaObjC/blocks.m10
2 files changed, 14 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index c7ba3cc822f..24388dd0f52 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -275,11 +275,12 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) {
// - it is an implicit integral conversion applied to an
// enumerator-like expression of type T or
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
- // We can only see integral conversions in valid enumerator-like
- // expressions.
+ // We can sometimes see integral conversions in valid
+ // enumerator-like expressions.
if (ICE->getCastKind() == CK_IntegralCast)
return findEnumForBlockReturn(ICE->getSubExpr());
- return 0;
+
+ // Otherwise, just rely on the type.
}
// - it is an expression of that formal enum type.
diff --git a/clang/test/SemaObjC/blocks.m b/clang/test/SemaObjC/blocks.m
index b523e4c9163..65434698a85 100644
--- a/clang/test/SemaObjC/blocks.m
+++ b/clang/test/SemaObjC/blocks.m
@@ -86,9 +86,11 @@ typedef enum CStyleEnum (^cse_block_t)();
void testCStyleEnumInference(bool arg) {
cse_block_t a;
+ enum CStyleEnum value;
// No warnings here.
a = ^{ return getCSE(); };
+ a = ^{ return value; };
a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
return 1;
@@ -102,6 +104,7 @@ void testCStyleEnumInference(bool arg) {
// No warnings here.
a = ^{ if (arg) return CSE_Value; else return getCSE(); };
a = ^{ if (arg) return getCSE(); else return CSE_Value; };
+ a = ^{ if (arg) return value; else return CSE_Value; };
// These two blocks actually return 'int'
a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
@@ -118,6 +121,13 @@ void testCStyleEnumInference(bool arg) {
return 1;
};
+ a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
+ if (arg)
+ return 1;
+ else
+ return value; // expected-error {{return type 'enum CStyleEnum' must match previous return type 'int'}}
+ };
+
// rdar://13200889
extern void check_enum(void);
a = ^{
OpenPOWER on IntegriCloud