Loading clang/lib/Sema/SemaLambda.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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. Loading clang/test/SemaObjC/blocks.m +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)'}} Loading @@ -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 = ^{ Loading Loading
clang/lib/Sema/SemaLambda.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -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. Loading
clang/test/SemaObjC/blocks.m +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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)'}} Loading @@ -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 = ^{ Loading