| Hi John, This test case: id test_dict() { return @{ @"a": [](){}, @"b": [](){} }; } Crashes in IRGen because ExprWithCleanups for the dummy BlockDecl we use to facilitate lambda to block conversion is at the wrong place. This happens because a lambda _expression_ is considered a full _expression_ so it calls MaybeCreateExprWithCleanups (see Sema::BuildBlockForLambdaConversion). which ends up adding the clean up code for the BlockDecl of the first lambda to the _expression_ for the 2nd lambda! Ideally, MaybeCreateExprWithCleanups should be called when the entire dictionary literal is seen. But in this case, this does not happen. Attached patch fixes this by making sure that after ‘every’ parse of the ‘value’ _expression_ MaybeCreateExprWithCleanups is called. This, in effect, assumes that the ‘value’ literal is a full _expression_. I don’t know the ramification of this change in the common case as couple of non-lambda literal tests broke. (it now generates the none-exc version of call instead of exc versions in couple of places). Please review. Let me know if you need additional info. - Thanks, Fariborz |
Index: lib/Sema/SemaExprObjC.cpp
===================================================================
--- lib/Sema/SemaExprObjC.cpp (revision 217780)
+++ lib/Sema/SemaExprObjC.cpp (working copy)
@@ -768,6 +768,10 @@
if (Converted.isInvalid())
return ExprError();
+ // Array literal index may have expressions which require
+ // cleanup.
+ Converted = MaybeCreateExprWithCleanups(Converted.get());
+
ElementsBuffer[I] = Converted.get();
}
@@ -951,6 +955,9 @@
= CheckObjCCollectionLiteralElement(*this, Elements[I].Value, ValueT);
if (Value.isInvalid())
return ExprError();
+ // Dictionary literal value may have expressions which require
+ // cleanup.
+ Value = MaybeCreateExprWithCleanups(Value.get());
Elements[I].Key = Key.get();
Elements[I].Value = Value.get();
Index: test/CodeGenObjCXX/lambda-in-objc-literals.mm
===================================================================
--- test/CodeGenObjCXX/lambda-in-objc-literals.mm (revision 0)
+++ test/CodeGenObjCXX/lambda-in-objc-literals.mm (working copy)
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s
-fexceptions -std=c++11 -fblocks
+// rdar://16879958
+
+@protocol NSCopying @end
+typedef unsigned long NSUInteger;
+typedef long NSInteger;
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying>
[])keys count:(NSUInteger)cnt;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+- (id)objectForKeyedSubscript:(id)key;
++ (id) alloc;
+- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys
count:(unsigned long)cnt;
+@end
+
+@interface NSString<NSCopying>
+@end
+
+
+@class NSFastEnumerationState;
+
+@protocol NSFastEnumeration
+
+- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id [])buffer count:(NSUInteger)len;
+
+@end
+
+@interface NSNumber
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+@interface NSArray <NSFastEnumeration>
++ (id) alloc;
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+@end
+
+id test_dict()
+{
+ return @{
+ @"a": [](){},
+ @"b": [](){},
+ @"c": [](){}
+ };
+}
+
+id test_arr()
+{
+ return @[
+ [](){},
+ [](){}
+ ];
+}
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
