Commit 1b4259b5 authored by John McCall's avatar John McCall
Browse files

In block enum-return inference, don't die on loads of enum lvalues.

More of rdar://13200889.

llvm-svn: 181390
parent 220dd334
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -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.
+10 −0
Original line number Diff line number Diff line
@@ -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 = ^{