From: Douglas Gregor Date: Thu, 2 May 2013 18:35:56 +0000 (+0000) Subject: Fix crasher when the range in a C++ range-for loop has an ill-formed initializer. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39b60dc786950e553f5e12fa0e692a33f650a568;p=clang Fix crasher when the range in a C++ range-for loop has an ill-formed initializer. Fixes . 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 925860a600..fda154820a 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1346,6 +1346,9 @@ public: if (DeclStmt *RangeStmt = dyn_cast(Range)) { if (RangeStmt->isSingleDecl()) { if (VarDecl *RangeVar = dyn_cast(RangeStmt->getSingleDecl())) { + if (RangeVar->isInvalidDecl()) + return StmtError(); + Expr *RangeExpr = RangeVar->getInit(); if (!RangeExpr->isTypeDependent() && RangeExpr->getType()->isObjCObjectPointerType()) @@ -5948,12 +5951,15 @@ TreeTransform::TransformCXXForRangeStmt(CXXForRangeStmt *S) { 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 @@ TreeTransform::TransformCXXForRangeStmt(CXXForRangeStmt *S) { // 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 3952afdeff..b159a15b8d 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 @@ void example() { for (int &x : array) x *= 2; } + +namespace rdar13712739 { + template + 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}} +}