diff options
author | Manman Ren <manman.ren@gmail.com> | 2016-02-02 22:23:03 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2016-02-02 22:23:03 +0000 |
commit | 8abc2e51b81efe2f540f6a61a3028f8fe72fe478 (patch) | |
tree | 2556dd45ca4238752886651c46b6d3dd0b338a19 | |
parent | c67466054f8dd467283f17fd31c2c7763ab25016 (diff) | |
download | bcm5719-llvm-8abc2e51b81efe2f540f6a61a3028f8fe72fe478.tar.gz bcm5719-llvm-8abc2e51b81efe2f540f6a61a3028f8fe72fe478.zip |
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
llvm-svn: 259591
-rw-r--r-- | clang/lib/AST/Expr.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/block-for-lambda-conversion.mm | 27 |
2 files changed, 34 insertions, 2 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 1b62a7b579e..5590527819e 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/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<CXXConstructExpr>(SubExpr)->getArg(0); - else if (E->getCastKind() == CK_UserDefinedConversion) - SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); + else if (E->getCastKind() == CK_UserDefinedConversion) { + assert((isa<CXXMemberCallExpr>(SubExpr) || + isa<BlockExpr>(SubExpr)) && + "Unexpected SubExpr for CK_UserDefinedConversion."); + if (isa<CXXMemberCallExpr>(SubExpr)) + SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); + } // If the subexpression we're left with is an implicit cast, look // through that, too. diff --git a/clang/test/SemaObjCXX/block-for-lambda-conversion.mm b/clang/test/SemaObjCXX/block-for-lambda-conversion.mm new file mode 100644 index 00000000000..671e83dc220 --- /dev/null +++ b/clang/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; + }]; +} |