Clean up the analysis of the collection operand to ObjC
for-in statements; specifically, make sure to close over any
temporaries or cleanups it might require. In ARC, this has
implications for the lifetime of the collection, so emit it
with a retain and release it upon exit from the loop.
rdar://problem/9817306
llvm-svn: 136204
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 622c8ea..b34e4f8 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1405,13 +1405,22 @@
// statememt before parsing the body, in order to be able to deduce the type
// of an auto-typed loop variable.
StmtResult ForRangeStmt;
- if (ForRange)
+ if (ForRange) {
ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, LParenLoc,
FirstPart.take(),
ForRangeInit.ColonLoc,
ForRangeInit.RangeExpr.get(),
RParenLoc);
+
+ // Similarly, we need to do the semantic analysis for a for-range
+ // statement immediately in order to close over temporaries correctly.
+ } else if (ForEach) {
+ if (!Collection.isInvalid())
+ Collection =
+ Actions.ActOnObjCForCollectionOperand(ForLoc, Collection.take());
+ }
+
// C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
// if the body isn't a compound statement to avoid push/pop in common cases.
@@ -1439,8 +1448,6 @@
return StmtError();
if (ForEach)
- // FIXME: It isn't clear how to communicate the late destruction of
- // C++ temporaries used to create the collection.
return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
FirstPart.take(),
Collection.take(), RParenLoc,