r180937 - Fix crasher when the range in a C++ range-for loop has an ill-formed initializer.

Douglas Gregor dgregor at apple.com
Thu May 2 11:35:56 PDT 2013


Author: dgregor
Date: Thu May  2 13:35:56 2013
New Revision: 180937

URL: http://llvm.org/viewvc/llvm-project?rev=180937&view=rev
Log:
Fix crasher when the range in a C++ range-for loop has an ill-formed initializer.

Fixes <rdar://problem/13712739>.

Modified:
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=180937&r1=180936&r2=180937&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu May  2 13:35:56 2013
@@ -1346,6 +1346,9 @@ public:
     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 @@ TreeTransform<Derived>::TransformCXXForR
       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<Derived>::TransformCXXForR
 
   // 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);

Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp?rev=180937&r1=180936&r2=180937&view=diff
==============================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp (original)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp Thu May  2 13:35:56 2013
@@ -242,3 +242,13 @@ void example() {
   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}}
+}





More information about the cfe-commits mailing list