Author: rjmccall Date: Sat Apr 7 10:42:06 2018 New Revision: 329508 URL: http://llvm.org/viewvc/llvm-project?rev=329508&view=rev Log: Allow equality comparisons between block pointers and block-pointer-compatible ObjC object pointer types.
Patch by Dustin Howett! Added: cfe/trunk/test/SemaObjC/block-compare.mm Modified: cfe/trunk/lib/Sema/SemaExpr.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=329508&r1=329507&r2=329508&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Apr 7 10:42:06 2018 @@ -10029,6 +10029,19 @@ QualType Sema::CheckCompareOperands(Expr RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast); return ResultTy; } + + if (!IsRelational && LHSType->isBlockPointerType() && + RHSType->isBlockCompatibleObjCPointerType(Context)) { + LHS = ImpCastExprToType(LHS.get(), RHSType, + CK_BlockPointerToObjCPointerCast); + return ResultTy; + } else if (!IsRelational && + LHSType->isBlockCompatibleObjCPointerType(Context) && + RHSType->isBlockPointerType()) { + RHS = ImpCastExprToType(RHS.get(), LHSType, + CK_BlockPointerToObjCPointerCast); + return ResultTy; + } } if ((LHSType->isAnyPointerType() && RHSType->isIntegerType()) || (LHSType->isIntegerType() && RHSType->isAnyPointerType())) { Added: cfe/trunk/test/SemaObjC/block-compare.mm URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/block-compare.mm?rev=329508&view=auto ============================================================================== --- cfe/trunk/test/SemaObjC/block-compare.mm (added) +++ cfe/trunk/test/SemaObjC/block-compare.mm Sat Apr 7 10:42:06 2018 @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -S -o - -triple i686-windows -verify -fblocks \ +// RUN: -Wno-unused-comparison %s + +#pragma clang diagnostic ignored "-Wunused-comparison" + +#define nil ((id)nullptr) + +@protocol NSObject +@end + +@protocol NSCopying +@end + +@protocol OtherProtocol +@end + +__attribute__((objc_root_class)) +@interface NSObject <NSObject, NSCopying> +@end + +__attribute__((objc_root_class)) +@interface Test +@end + +int main() { + void (^block)() = ^{}; + NSObject *object; + id<NSObject, NSCopying> qualifiedId; + + id<OtherProtocol> poorlyQualified1; + Test *objectOfWrongType; + + block == nil; + block == object; + block == qualifiedId; + + nil == block; + object == block; + qualifiedId == block; + + // these are still not valid: blocks must be compared with id, NSObject*, or a protocol-qualified id + // conforming to NSCopying or NSObject. + + block == poorlyQualified1; // expected-error {{invalid operands to binary expression ('void (^)()' and 'id<OtherProtocol>')}} + block == objectOfWrongType; // expected-error {{invalid operands to binary expression ('void (^)()' and 'Test *')}} + + poorlyQualified1 == block; // expected-error {{invalid operands to binary expression ('id<OtherProtocol>' and 'void (^)()')}} + objectOfWrongType == block; // expected-error {{invalid operands to binary expression ('Test *' and 'void (^)()')}} + + return 0; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits