From: Manman Ren Date: Tue, 2 Feb 2016 22:23:03 +0000 (+0000) Subject: ObjCXX: fix a crash during typo correction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fcd11968f1040e9d89dc32fed1148f667f75890;p=clang ObjCXX: fix a crash during typo correction. For ObjCXX, we can create a CastExpr with Kind being CK_UserDefinedConversion and SubExpr being BlockExpr. Specifically one can return BlockExpr from BuildCXXMemberCallExpr and the result can be used to build a CastExpr. Fix the assumption in CastExpr::getSubExprAsWritten that SubExpr can only be CXXMemberCallExpr. rdar://problem/24364077 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259591 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 1b62a7b579..5590527819 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1744,8 +1744,13 @@ Expr *CastExpr::getSubExprAsWritten() { // subexpression describing the call; strip it off. if (E->getCastKind() == CK_ConstructorConversion) SubExpr = cast(SubExpr)->getArg(0); - else if (E->getCastKind() == CK_UserDefinedConversion) - SubExpr = cast(SubExpr)->getImplicitObjectArgument(); + else if (E->getCastKind() == CK_UserDefinedConversion) { + assert((isa(SubExpr) || + isa(SubExpr)) && + "Unexpected SubExpr for CK_UserDefinedConversion."); + if (isa(SubExpr)) + SubExpr = cast(SubExpr)->getImplicitObjectArgument(); + } // If the subexpression we're left with is an implicit cast, look // through that, too. diff --git a/test/SemaObjCXX/block-for-lambda-conversion.mm b/test/SemaObjCXX/block-for-lambda-conversion.mm new file mode 100644 index 0000000000..671e83dc22 --- /dev/null +++ b/test/SemaObjCXX/block-for-lambda-conversion.mm @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -std=c++11 %s + +enum NSEventType { + NSEventTypeFlagsChanged = 12 +}; + +enum NSEventMask { + NSEventMaskLeftMouseDown = 1 +}; + +static const NSEventType NSFlagsChanged = NSEventTypeFlagsChanged; + +@interface NSObject +@end +@interface NSEvent : NSObject { +} ++ (nullable id) +addMonitor:(NSEventMask)mask handler:(NSEvent *_Nullable (^)(NSEvent *))block; +@end + +void test(id weakThis) { + id m_flagsChangedEventMonitor = [NSEvent + addMonitor:NSFlagsChangedMask //expected-error {{use of undeclared identifier 'NSFlagsChangedMask'}} + handler:[weakThis](NSEvent *flagsChangedEvent) { + return flagsChangedEvent; + }]; +}