Fix crasher when the range in a C++ range-for loop has an ill-formed initializer.
Fixes <rdar://problem/13712739>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180937 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 925860a..fda1548 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1346,6 +1346,9 @@
if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
if (RangeStmt->isSingleDecl()) {
if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
+ if (RangeVar->isInvalidDecl())
+ return StmtError();
+
Expr *RangeExpr = RangeVar->getInit();
if (!RangeExpr->isTypeDependent() &&
RangeExpr->getType()->isObjCObjectPointerType())
@@ -5948,12 +5951,15 @@
BeginEnd.get() != S->getBeginEndStmt() ||
Cond.get() != S->getCond() ||
Inc.get() != S->getInc() ||
- LoopVar.get() != S->getLoopVarStmt())
+ LoopVar.get() != S->getLoopVarStmt()) {
NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
S->getColonLoc(), Range.get(),
BeginEnd.get(), Cond.get(),
Inc.get(), LoopVar.get(),
S->getRParenLoc());
+ if (NewStmt.isInvalid())
+ return StmtError();
+ }
StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
@@ -5961,12 +5967,15 @@
// Body has changed but we didn't rebuild the for-range statement. Rebuild
// it now so we have a new statement to attach the body to.
- if (Body.get() != S->getBody() && NewStmt.get() == S)
+ if (Body.get() != S->getBody() && NewStmt.get() == S) {
NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
S->getColonLoc(), Range.get(),
BeginEnd.get(), Cond.get(),
Inc.get(), LoopVar.get(),
S->getRParenLoc());
+ if (NewStmt.isInvalid())
+ return StmtError();
+ }
if (NewStmt.get() == S)
return SemaRef.Owned(S);
diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
index 3952afd..b159a15 100644
--- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
@@ -242,3 +242,13 @@
for (int &x : array)
x *= 2;
}
+
+namespace rdar13712739 {
+ template<typename T>
+ void foo(const T& t) {
+ auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}}
+ for (auto &blah : x) { }
+ }
+
+ template void foo(const int&); // expected-note{{in instantiation of function template specialization}}
+}