summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-02-02 22:23:03 +0000
committerManman Ren <manman.ren@gmail.com>2016-02-02 22:23:03 +0000
commit8abc2e51b81efe2f540f6a61a3028f8fe72fe478 (patch)
tree2556dd45ca4238752886651c46b6d3dd0b338a19
parentc67466054f8dd467283f17fd31c2c7763ab25016 (diff)
downloadbcm5719-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.cpp9
-rw-r--r--clang/test/SemaObjCXX/block-for-lambda-conversion.mm27
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;
+ }];
+}
OpenPOWER on IntegriCloud