<div dir="ltr">This breaks Wfor-loop-analysis. Code (e.g. WebKit) has a pattern where a class has an accessor that takes an index and returns an element if the index is in bounds or nullptr else, and calling code passes indices starting at 0 until a nullptr element is returned. That used to be fine, but now clang warns:<div><br></div><div><div>../../third_party/WebKit/Source/core/html/HTMLInputElement.cpp(1843,49):  error: variable 'option' used in loop condition not modified in loop body [-Werror,-Wfor-loop-analysis]</div><div>        for (unsigned i = 0; HTMLOptionElement* option = options->item(i); ++i) {</div><div>                                                ^~~~~~</div></div><div><br></div><div>(in many other places too.)</div><div><br></div><div>Can you take a look?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 23, 2016 at 4:41 AM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Thu Jun 23 03:41:20 2016<br>
New Revision: 273548<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=273548&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=273548&view=rev</a><br>
Log:<br>
Rearrange condition handling so that semantic checks on a condition variable<br>
are performed before the other substatements of the construct are parsed,<br>
rather than deferring them until the end. This allows better error recovery<br>
from semantic errors in the condition, improves diagnostic order, and is a<br>
prerequisite for C++17 constexpr if.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Parse/Parser.h<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
    cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
    cfe/trunk/lib/Parse/ParseStmt.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/lib/Sema/TreeTransform.h<br>
    cfe/trunk/test/FixIt/fixit-vexing-parse.cpp<br>
    cfe/trunk/test/Parser/cxx0x-condition.cpp<br>
    cfe/trunk/test/SemaCXX/crashes.cpp<br>
    cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
    cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a><br>
<br>
Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 23 03:41:20 2016<br>
@@ -1588,8 +1588,8 @@ private:<br>
<br>
   //===--------------------------------------------------------------------===//<br>
   // C++ if/switch/while condition expression.<br>
-  bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,<br>
-                         SourceLocation Loc, bool ConvertToBoolean);<br>
+  Sema::ConditionResult ParseCXXCondition(SourceLocation Loc,<br>
+                                          Sema::ConditionKind CK);<br>
<br>
   //===--------------------------------------------------------------------===//<br>
   // C++ Coroutines<br>
@@ -1680,10 +1680,9 @@ private:<br>
                                     unsigned ScopeFlags);<br>
   void ParseCompoundStatementLeadingPragmas();<br>
   StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);<br>
-  bool ParseParenExprOrCondition(ExprResult &ExprResult,<br>
-                                 Decl *&DeclResult,<br>
+  bool ParseParenExprOrCondition(Sema::ConditionResult &CondResult,<br>
                                  SourceLocation Loc,<br>
-                                 bool ConvertToBoolean);<br>
+                                 Sema::ConditionKind CK);<br>
   StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);<br>
   StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);<br>
   StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 03:41:20 2016<br>
@@ -3298,6 +3298,7 @@ public:<br>
 public:<br>
   class FullExprArg {<br>
   public:<br>
+    FullExprArg() : E(nullptr) { }<br>
     FullExprArg(Sema &actions) : E(nullptr) { }<br>
<br>
     ExprResult release() {<br>
@@ -3391,27 +3392,23 @@ public:<br>
                                  ArrayRef<const Attr*> Attrs,<br>
                                  Stmt *SubStmt);<br>
<br>
-  StmtResult ActOnIfStmt(SourceLocation IfLoc,<br>
-                         FullExprArg CondVal, Decl *CondVar,<br>
-                         Stmt *ThenVal,<br>
-                         SourceLocation ElseLoc, Stmt *ElseVal);<br>
+  class ConditionResult;<br>
+  StmtResult ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,<br>
+                         Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);<br>
   StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,<br>
-                                            Expr *Cond,<br>
-                                            Decl *CondVar);<br>
+                                    ConditionResult Cond);<br>
   StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,<br>
                                            Stmt *Switch, Stmt *Body);<br>
-  StmtResult ActOnWhileStmt(SourceLocation WhileLoc,<br>
-                            FullExprArg Cond,<br>
-                            Decl *CondVar, Stmt *Body);<br>
+  StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,<br>
+                            Stmt *Body);<br>
   StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,<br>
-                                 SourceLocation WhileLoc,<br>
-                                 SourceLocation CondLParen, Expr *Cond,<br>
-                                 SourceLocation CondRParen);<br>
+                         SourceLocation WhileLoc, SourceLocation CondLParen,<br>
+                         Expr *Cond, SourceLocation CondRParen);<br>
<br>
   StmtResult ActOnForStmt(SourceLocation ForLoc,<br>
                           SourceLocation LParenLoc,<br>
-                          Stmt *First, FullExprArg Second,<br>
-                          Decl *SecondVar,<br>
+                          Stmt *First,<br>
+                          ConditionResult Second,<br>
                           FullExprArg Third,<br>
                           SourceLocation RParenLoc,<br>
                           Stmt *Body);<br>
@@ -4801,11 +4798,6 @@ public:<br>
                             bool WarnOnNonAbstractTypes,<br>
                             SourceLocation DtorLoc);<br>
<br>
-  DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);<br>
-  ExprResult CheckConditionVariable(VarDecl *ConditionVar,<br>
-                                    SourceLocation StmtLoc,<br>
-                                    bool ConvertToBoolean);<br>
-<br>
   ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,<br>
                                Expr *Operand, SourceLocation RParen);<br>
   ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,<br>
@@ -8923,6 +8915,46 @@ public:<br>
   /// type, and if so, emit a note describing what happened.<br>
   void EmitRelatedResultTypeNoteForReturn(QualType destType);<br>
<br>
+  class ConditionResult {<br>
+    Decl *ConditionVar;<br>
+    FullExprArg Condition;<br>
+    bool Invalid;<br>
+<br>
+    friend class Sema;<br>
+    ConditionResult(Decl *ConditionVar, FullExprArg Condition)<br>
+        : ConditionVar(ConditionVar), Condition(Condition), Invalid(false) {}<br>
+    explicit ConditionResult(bool Invalid)<br>
+        : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid) {}<br>
+<br>
+  public:<br>
+    ConditionResult() : ConditionResult(false) {}<br>
+    bool isInvalid() const { return Invalid; }<br>
+    std::pair<VarDecl *, Expr *> get() const {<br>
+      return std::make_pair(cast_or_null<VarDecl>(ConditionVar),<br>
+                            Condition.get());<br>
+    }<br>
+  };<br>
+  static ConditionResult ConditionError() { return ConditionResult(true); }<br>
+<br>
+  enum class ConditionKind {<br>
+    Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'.<br>
+    Switch   ///< An integral condition for a 'switch' statement.<br>
+  };<br>
+<br>
+  ConditionResult ActOnCondition(Scope *S, SourceLocation Loc,<br>
+                                 Expr *SubExpr, ConditionKind CK);<br>
+<br>
+  ConditionResult ActOnConditionVariable(Decl *ConditionVar,<br>
+                                         SourceLocation StmtLoc,<br>
+                                         ConditionKind CK);<br>
+<br>
+  DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);<br>
+<br>
+  ExprResult CheckConditionVariable(VarDecl *ConditionVar,<br>
+                                    SourceLocation StmtLoc,<br>
+                                    ConditionKind CK);<br>
+  ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond);<br>
+<br>
   /// CheckBooleanCondition - Diagnose problems involving the use of<br>
   /// the given expression as a boolean condition (e.g. in an if<br>
   /// statement).  Also performs the standard function and array<br>
@@ -8931,10 +8963,7 @@ public:<br>
   /// \param Loc - A location associated with the condition, e.g. the<br>
   /// 'if' keyword.<br>
   /// \return true iff there were any errors<br>
-  ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);<br>
-<br>
-  ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,<br>
-                                   Expr *SubExpr);<br>
+  ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E);<br>
<br>
   /// DiagnoseAssignmentAsCondition - Given that an expression is<br>
   /// being used as a boolean condition, warn if it's an assignment.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jun 23 03:41:20 2016<br>
@@ -3420,10 +3420,11 @@ Parser::tryParseExceptionSpecification(b<br>
     NoexceptExpr = ParseConstantExpression();<br>
     T.consumeClose();<br>
     // The argument must be contextually convertible to bool. We use<br>
-    // ActOnBooleanCondition for this purpose.<br>
+    // CheckBooleanCondition for this purpose.<br>
+    // FIXME: Add a proper Sema entry point for this.<br>
     if (!NoexceptExpr.isInvalid()) {<br>
-      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,<br>
-                                                   NoexceptExpr.get());<br>
+      NoexceptExpr =<br>
+          Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());<br>
       NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());<br>
     } else {<br>
       NoexceptType = EST_None;<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 23 03:41:20 2016<br>
@@ -1726,27 +1726,19 @@ Parser::ParseCXXTypeConstructExpression(<br>
 /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]<br>
 ///             '=' assignment-expression<br>
 ///<br>
-/// \param ExprOut if the condition was parsed as an expression, the parsed<br>
-/// expression.<br>
-///<br>
-/// \param DeclOut if the condition was parsed as a declaration, the parsed<br>
-/// declaration.<br>
-///<br>
 /// \param Loc The location of the start of the statement that requires this<br>
 /// condition, e.g., the "for" in a for loop.<br>
 ///<br>
 /// \param ConvertToBoolean Whether the condition expression should be<br>
 /// converted to a boolean value.<br>
 ///<br>
-/// \returns true if there was a parsing, false otherwise.<br>
-bool Parser::ParseCXXCondition(ExprResult &ExprOut,<br>
-                               Decl *&DeclOut,<br>
-                               SourceLocation Loc,<br>
-                               bool ConvertToBoolean) {<br>
+/// \returns The parsed condition.<br>
+Sema::ConditionResult Parser::ParseCXXCondition(SourceLocation Loc,<br>
+                                                Sema::ConditionKind CK) {<br>
   if (Tok.is(tok::code_completion)) {<br>
     Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);<br>
     cutOffParsing();<br>
-    return true;<br>
+    return Sema::ConditionError();<br>
   }<br>
<br>
   ParsedAttributesWithRange attrs(AttrFactory);<br>
@@ -1756,16 +1748,11 @@ bool Parser::ParseCXXCondition(ExprResul<br>
     ProhibitAttributes(attrs);<br>
<br>
     // Parse the expression.<br>
-    ExprOut = ParseExpression(); // expression<br>
-    DeclOut = nullptr;<br>
-    if (ExprOut.isInvalid())<br>
-      return true;<br>
-<br>
-    // If required, convert to a boolean value.<br>
-    if (ConvertToBoolean)<br>
-      ExprOut<br>
-        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());<br>
-    return ExprOut.isInvalid();<br>
+    ExprResult Expr = ParseExpression(); // expression<br>
+    if (Expr.isInvalid())<br>
+      return Sema::ConditionError();<br>
+<br>
+    return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK);<br>
   }<br>
<br>
   // type-specifier-seq<br>
@@ -1783,7 +1770,7 @@ bool Parser::ParseCXXCondition(ExprResul<br>
     ExprResult AsmLabel(ParseSimpleAsm(&Loc));<br>
     if (AsmLabel.isInvalid()) {<br>
       SkipUntil(tok::semi, StopAtSemi);<br>
-      return true;<br>
+      return Sema::ConditionError();<br>
     }<br>
     DeclaratorInfo.setAsmLabel(AsmLabel.get());<br>
     DeclaratorInfo.SetRangeEnd(Loc);<br>
@@ -1795,8 +1782,9 @@ bool Parser::ParseCXXCondition(ExprResul<br>
   // Type-check the declaration itself.<br>
   DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),<br>
                                                         DeclaratorInfo);<br>
-  DeclOut = Dcl.get();<br>
-  ExprOut = ExprError();<br>
+  if (Dcl.isInvalid())<br>
+    return Sema::ConditionError();<br>
+  Decl *DeclOut = Dcl.get();<br>
<br>
   // '=' assignment-expression<br>
   // If a '==' or '+=' is found, suggest a fixit to '='.<br>
@@ -1816,12 +1804,11 @@ bool Parser::ParseCXXCondition(ExprResul<br>
     SourceLocation LParen = ConsumeParen(), RParen = LParen;<br>
     if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))<br>
       RParen = ConsumeParen();<br>
-    Diag(DeclOut ? DeclOut->getLocation() : LParen,<br>
+    Diag(DeclOut->getLocation(),<br>
          diag::err_expected_init_in_condition_lparen)<br>
       << SourceRange(LParen, RParen);<br>
   } else {<br>
-    Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),<br>
-         diag::err_expected_init_in_condition);<br>
+    Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);<br>
   }<br>
<br>
   if (!InitExpr.isInvalid())<br>
@@ -1834,8 +1821,7 @@ bool Parser::ParseCXXCondition(ExprResul<br>
   // (This is currently handled by Sema).<br>
<br>
   Actions.FinalizeDeclaration(DeclOut);<br>
-<br>
-  return false;<br>
+  return Actions.ActOnConditionVariable(DeclOut, Loc, CK);<br>
 }<br>
<br>
 /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Jun 23 03:41:20 2016<br>
@@ -1052,29 +1052,28 @@ StmtResult Parser::ParseCompoundStatemen<br>
 /// should try to recover harder.  It returns false if the condition is<br>
 /// successfully parsed.  Note that a successful parse can still have semantic<br>
 /// errors in the condition.<br>
-bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,<br>
-                                       Decl *&DeclResult,<br>
+bool Parser::ParseParenExprOrCondition(Sema::ConditionResult &Cond,<br>
                                        SourceLocation Loc,<br>
-                                       bool ConvertToBoolean) {<br>
+                                       Sema::ConditionKind CK) {<br>
   BalancedDelimiterTracker T(*this, tok::l_paren);<br>
   T.consumeOpen();<br>
<br>
   if (getLangOpts().CPlusPlus)<br>
-    ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);<br>
+    Cond = ParseCXXCondition(Loc, CK);<br>
   else {<br>
-    ExprResult = ParseExpression();<br>
-    DeclResult = nullptr;<br>
+    ExprResult CondExpr = ParseExpression();<br>
<br>
     // If required, convert to a boolean value.<br>
-    if (!ExprResult.isInvalid() && ConvertToBoolean)<br>
-      ExprResult<br>
-        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());<br>
+    if (CondExpr.isInvalid())<br>
+      Cond = Sema::ConditionError();<br>
+    else<br>
+      Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK);<br>
   }<br>
<br>
   // If the parser was confused by the condition and we don't have a ')', try to<br>
   // recover by skipping ahead to a semi and bailing out.  If condexp is<br>
   // semantically invalid but we have well formed code, keep going.<br>
-  if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) {<br>
+  if (Cond.isInvalid() && Tok.isNot(tok::r_paren)) {<br>
     SkipUntil(tok::semi);<br>
     // Skipping may have stopped if it found the containing ')'.  If so, we can<br>
     // continue parsing the if statement.<br>
@@ -1132,13 +1131,10 @@ StmtResult Parser::ParseIfStatement(Sour<br>
   ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);<br>
<br>
   // Parse the condition.<br>
-  ExprResult CondExp;<br>
-  Decl *CondVar = nullptr;<br>
-  if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))<br>
+  Sema::ConditionResult Cond;<br>
+  if (ParseParenExprOrCondition(Cond, IfLoc, Sema::ConditionKind::Boolean))<br>
     return StmtError();<br>
<br>
-  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));<br>
-<br>
   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if<br>
   // there is no compound stmt.  C90 does not have this clause.  We only do this<br>
   // if the body isn't a compound statement to avoid push/pop in common cases.<br>
@@ -1221,8 +1217,8 @@ StmtResult Parser::ParseIfStatement(Sour<br>
   if (ElseStmt.isInvalid())<br>
     ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);<br>
<br>
-  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),<br>
-                             ElseLoc, ElseStmt.get());<br>
+  return Actions.ActOnIfStmt(IfLoc, Cond, ThenStmt.get(), ElseLoc,<br>
+                             ElseStmt.get());<br>
 }<br>
<br>
 /// ParseSwitchStatement<br>
@@ -1259,13 +1255,11 @@ StmtResult Parser::ParseSwitchStatement(<br>
   ParseScope SwitchScope(this, ScopeFlags);<br>
<br>
   // Parse the condition.<br>
-  ExprResult Cond;<br>
-  Decl *CondVar = nullptr;<br>
-  if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))<br>
+  Sema::ConditionResult Cond;<br>
+  if (ParseParenExprOrCondition(Cond, SwitchLoc, Sema::ConditionKind::Switch))<br>
     return StmtError();<br>
<br>
-  StmtResult Switch<br>
-    = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);<br>
+  StmtResult Switch = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond);<br>
<br>
   if (Switch.isInvalid()) {<br>
     // Skip the switch body.<br>
@@ -1347,13 +1341,10 @@ StmtResult Parser::ParseWhileStatement(S<br>
   ParseScope WhileScope(this, ScopeFlags);<br>
<br>
   // Parse the condition.<br>
-  ExprResult Cond;<br>
-  Decl *CondVar = nullptr;<br>
-  if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))<br>
+  Sema::ConditionResult Cond;<br>
+  if (ParseParenExprOrCondition(Cond, WhileLoc, Sema::ConditionKind::Boolean))<br>
     return StmtError();<br>
<br>
-  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));<br>
-<br>
   // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if<br>
   // there is no compound stmt.  C90 does not have this clause.  We only do this<br>
   // if the body isn't a compound statement to avoid push/pop in common cases.<br>
@@ -1374,10 +1365,10 @@ StmtResult Parser::ParseWhileStatement(S<br>
   InnerScope.Exit();<br>
   WhileScope.Exit();<br>
<br>
-  if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())<br>
+  if (Cond.isInvalid() || Body.isInvalid())<br>
     return StmtError();<br>
<br>
-  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());<br>
+  return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.get());<br>
 }<br>
<br>
 /// ParseDoStatement<br>
@@ -1535,12 +1526,10 @@ StmtResult Parser::ParseForStatement(Sou<br>
<br>
   bool ForEach = false, ForRange = false;<br>
   StmtResult FirstPart;<br>
-  bool SecondPartIsInvalid = false;<br>
-  FullExprArg SecondPart(Actions);<br>
+  Sema::ConditionResult SecondPart;<br>
   ExprResult Collection;<br>
   ForRangeInit ForRangeInit;<br>
   FullExprArg ThirdPart(Actions);<br>
-  Decl *SecondVar = nullptr;<br>
<br>
   if (Tok.is(tok::code_completion)) {<br>
     Actions.CodeCompleteOrdinaryName(getCurScope(),<br>
@@ -1645,7 +1634,7 @@ StmtResult Parser::ParseForStatement(Sou<br>
       Diag(Tok, diag::err_for_range_expected_decl)<br>
         << FirstPart.get()->getSourceRange();<br>
       SkipUntil(tok::r_paren, StopBeforeMatch);<br>
-      SecondPartIsInvalid = true;<br>
+      SecondPart = Sema::ConditionError();<br>
     } else {<br>
       if (!Value.isInvalid()) {<br>
         Diag(Tok, diag::err_expected_semi_for);<br>
@@ -1660,29 +1649,28 @@ StmtResult Parser::ParseForStatement(Sou<br>
<br>
   // Parse the second part of the for specifier.<br>
   getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);<br>
-  if (!ForEach && !ForRange) {<br>
-    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");<br>
+  if (!ForEach && !ForRange && !SecondPart.isInvalid()) {<br>
     // Parse the second part of the for specifier.<br>
     if (Tok.is(tok::semi)) {  // for (...;;<br>
       // no second part.<br>
     } else if (Tok.is(tok::r_paren)) {<br>
       // missing both semicolons.<br>
     } else {<br>
-      ExprResult Second;<br>
       if (getLangOpts().CPlusPlus)<br>
-        ParseCXXCondition(Second, SecondVar, ForLoc, true);<br>
+        SecondPart = ParseCXXCondition(ForLoc, Sema::ConditionKind::Boolean);<br>
       else {<br>
-        Second = ParseExpression();<br>
-        if (!Second.isInvalid())<br>
-          Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc,<br>
-                                                 Second.get());<br>
+        ExprResult SecondExpr = ParseExpression();<br>
+        if (SecondExpr.isInvalid())<br>
+          SecondPart = Sema::ConditionError();<br>
+        else<br>
+          SecondPart =<br>
+              Actions.ActOnCondition(getCurScope(), ForLoc, SecondExpr.get(),<br>
+                                     Sema::ConditionKind::Boolean);<br>
       }<br>
-      SecondPartIsInvalid = Second.isInvalid();<br>
-      SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);<br>
     }<br>
<br>
     if (Tok.isNot(tok::semi)) {<br>
-      if (!SecondPartIsInvalid || SecondVar)<br>
+      if (!SecondPart.isInvalid())<br>
         Diag(Tok, diag::err_expected_semi_for);<br>
       else<br>
         // Skip until semicolon or rparen, don't consume it.<br>
@@ -1781,8 +1769,8 @@ StmtResult Parser::ParseForStatement(Sou<br>
     return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());<br>
<br>
   return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),<br>
-                              SecondPart, SecondVar, ThirdPart,<br>
-                              T.getCloseLocation(), Body.get());<br>
+                              SecondPart, ThirdPart, T.getCloseLocation(),<br>
+                              Body.get());<br>
 }<br>
<br>
 /// ParseGotoStatement<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 23 03:41:20 2016<br>
@@ -10092,10 +10092,10 @@ buildSingleCopyAssignRecursively(Sema &S<br>
                                     SizeType, VK_LValue, OK_Ordinary, Loc);<br>
<br>
   // Construct the loop that copies all elements of this array.<br>
-  return S.ActOnForStmt(Loc, Loc, InitStmt,<br>
-                        S.MakeFullExpr(Comparison),<br>
-                        nullptr, S.MakeFullDiscardedValueExpr(Increment),<br>
-                        Loc, Copy.get());<br>
+  return S.ActOnForStmt(<br>
+      Loc, Loc, InitStmt,<br>
+      S.ActOnCondition(nullptr, Loc, Comparison, Sema::ConditionKind::Boolean),<br>
+      S.MakeFullDiscardedValueExpr(Increment), Loc, Copy.get());<br>
 }<br>
<br>
 static StmtResult<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 03:41:20 2016<br>
@@ -14341,7 +14341,7 @@ void Sema::DiagnoseEqualityWithExtraPare<br>
     }<br>
 }<br>
<br>
-ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) {<br>
+ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E) {<br>
   DiagnoseAssignmentAsCondition(E);<br>
   if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))<br>
     DiagnoseEqualityWithExtraParens(parenE);<br>
@@ -14371,12 +14371,26 @@ ExprResult Sema::CheckBooleanCondition(E<br>
   return E;<br>
 }<br>
<br>
-ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,<br>
-                                       Expr *SubExpr) {<br>
+Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,<br>
+                                           Expr *SubExpr, ConditionKind CK) {<br>
+  // Empty conditions are valid in for-statements.<br>
   if (!SubExpr)<br>
-    return ExprError();<br>
+    return ConditionResult();<br>
<br>
-  return CheckBooleanCondition(SubExpr, Loc);<br>
+  ExprResult Cond;<br>
+  switch (CK) {<br>
+  case ConditionKind::Boolean:<br>
+    Cond = CheckBooleanCondition(Loc, SubExpr);<br>
+    break;<br>
+<br>
+  case ConditionKind::Switch:<br>
+    Cond = CheckSwitchCondition(Loc, SubExpr);<br>
+    break;<br>
+  }<br>
+  if (Cond.isInvalid())<br>
+    return ConditionError();<br>
+<br>
+  return ConditionResult(nullptr, MakeFullExpr(Cond.get(), Loc));<br>
 }<br>
<br>
 namespace {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 03:41:20 2016<br>
@@ -3054,11 +3054,21 @@ void Sema::CheckVirtualDtorCall(CXXDestr<br>
   }<br>
 }<br>
<br>
+Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,<br>
+                                                   SourceLocation StmtLoc,<br>
+                                                   ConditionKind CK) {<br>
+  ExprResult E =<br>
+      CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);<br>
+  if (E.isInvalid())<br>
+    return ConditionError();<br>
+  return ConditionResult(ConditionVar, MakeFullExpr(E.get(), StmtLoc));<br>
+}<br>
+<br>
 /// \brief Check the use of the given variable as a C++ condition in an if,<br>
 /// while, do-while, or switch statement.<br>
 ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,<br>
                                         SourceLocation StmtLoc,<br>
-                                        bool ConvertToBoolean) {<br>
+                                        ConditionKind CK) {<br>
   if (ConditionVar->isInvalidDecl())<br>
     return ExprError();<br>
<br>
@@ -3082,13 +3092,15 @@ ExprResult Sema::CheckConditionVariable(<br>
<br>
   MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));<br>
<br>
-  if (ConvertToBoolean) {<br>
-    Condition = CheckBooleanCondition(Condition.get(), StmtLoc);<br>
-    if (Condition.isInvalid())<br>
-      return ExprError();<br>
+  switch (CK) {<br>
+  case ConditionKind::Boolean:<br>
+    return CheckBooleanCondition(StmtLoc, Condition.get());<br>
+<br>
+  case ConditionKind::Switch:<br>
+    return CheckSwitchCondition(StmtLoc, Condition.get());<br>
   }<br>
<br>
-  return Condition;<br>
+  llvm_unreachable("unexpected condition kind");<br>
 }<br>
<br>
 /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 23 03:41:20 2016<br>
@@ -6826,12 +6826,11 @@ OMPClause *Sema::ActOnOpenMPIfClause(Ope<br>
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&<br>
       !Condition->isInstantiationDependent() &&<br>
       !Condition->containsUnexpandedParameterPack()) {<br>
-    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),<br>
-                                           Condition->getExprLoc(), Condition);<br>
+    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);<br>
     if (Val.isInvalid())<br>
       return nullptr;<br>
<br>
-    ValExpr = Val.get();<br>
+    ValExpr = MakeFullExpr(Val.get()).get();<br>
   }<br>
<br>
   return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,<br>
@@ -6846,12 +6845,11 @@ OMPClause *Sema::ActOnOpenMPFinalClause(<br>
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&<br>
       !Condition->isInstantiationDependent() &&<br>
       !Condition->containsUnexpandedParameterPack()) {<br>
-    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),<br>
-                                           Condition->getExprLoc(), Condition);<br>
+    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);<br>
     if (Val.isInvalid())<br>
       return nullptr;<br>
<br>
-    ValExpr = Val.get();<br>
+    ValExpr = MakeFullExpr(Val.get()).get();<br>
   }<br>
<br>
   return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jun 23 03:41:20 2016<br>
@@ -504,39 +504,30 @@ public:<br>
 }<br>
<br>
 StmtResult<br>
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,<br>
+Sema::ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,<br>
                   Stmt *thenStmt, SourceLocation ElseLoc,<br>
                   Stmt *elseStmt) {<br>
-  ExprResult CondResult(CondVal.release());<br>
-<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (CondVar) {<br>
-    ConditionVar = cast<VarDecl>(CondVar);<br>
-    CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);<br>
-    CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);<br>
+  auto CondVal = Cond.get();<br>
+  if (Cond.isInvalid()) {<br>
+    CondVal.first = nullptr;<br>
+    CondVal.second = new (Context)<br>
+        OpaqueValueExpr(SourceLocation(), Context.BoolTy, VK_RValue);<br>
   }<br>
-  Expr *ConditionExpr = CondResult.getAs<Expr>();<br>
-  if (ConditionExpr) {<br>
-<br>
-    if (!Diags.isIgnored(diag::warn_comma_operator,<br>
-                         ConditionExpr->getExprLoc()))<br>
-      CommaVisitor(*this).Visit(ConditionExpr);<br>
<br>
-    DiagnoseUnusedExprResult(thenStmt);<br>
+  if (!Diags.isIgnored(diag::warn_comma_operator,<br>
+                       CondVal.second->getExprLoc()))<br>
+    CommaVisitor(*this).Visit(CondVal.second);<br>
<br>
-    if (!elseStmt) {<br>
-      DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,<br>
-                            diag::warn_empty_if_body);<br>
-    }<br>
+  DiagnoseUnusedExprResult(thenStmt);<br>
<br>
-    DiagnoseUnusedExprResult(elseStmt);<br>
-  } else {<br>
-    // Create a dummy Expr for the condition for error recovery<br>
-    ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(),<br>
-                                                  Context.BoolTy, VK_RValue);<br>
+  if (!elseStmt) {<br>
+    DiagnoseEmptyStmtBody(CondVal.second->getLocEnd(), thenStmt,<br>
+                          diag::warn_empty_if_body);<br>
   }<br>
<br>
-  return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,<br>
+  DiagnoseUnusedExprResult(elseStmt);<br>
+<br>
+  return new (Context) IfStmt(Context, IfLoc, CondVal.first, CondVal.second,<br>
                               thenStmt, ElseLoc, elseStmt);<br>
 }<br>
<br>
@@ -599,24 +590,7 @@ static QualType GetTypeBeforeIntegralPro<br>
   return expr->getType();<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,<br>
-                             Decl *CondVar) {<br>
-  ExprResult CondResult;<br>
-<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (CondVar) {<br>
-    ConditionVar = cast<VarDecl>(CondVar);<br>
-    CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);<br>
-    if (CondResult.isInvalid())<br>
-      return StmtError();<br>
-<br>
-    Cond = CondResult.get();<br>
-  }<br>
-<br>
-  if (!Cond)<br>
-    return StmtError();<br>
-<br>
+ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {<br>
   class SwitchConvertDiagnoser : public ICEConvertDiagnoser {<br>
     Expr *Cond;<br>
<br>
@@ -664,24 +638,24 @@ Sema::ActOnStartOfSwitchStmt(SourceLocat<br>
     }<br>
   } SwitchDiagnoser(Cond);<br>
<br>
-  CondResult =<br>
+  ExprResult CondResult =<br>
       PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);<br>
-  if (CondResult.isInvalid()) return StmtError();<br>
-  Cond = CondResult.get();<br>
+  if (CondResult.isInvalid())<br>
+    return ExprError();<br>
<br>
   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.<br>
-  CondResult = UsualUnaryConversions(Cond);<br>
-  if (CondResult.isInvalid()) return StmtError();<br>
-  Cond = CondResult.get();<br>
+  return UsualUnaryConversions(CondResult.get());<br>
+}<br>
<br>
-  CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);<br>
-  if (CondResult.isInvalid())<br>
+StmtResult<br>
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ConditionResult Cond) {<br>
+  if (Cond.isInvalid())<br>
     return StmtError();<br>
-  Cond = CondResult.get();<br>
<br>
   getCurFunction()->setHasBranchIntoScope();<br>
<br>
-  SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);<br>
+  SwitchStmt *SS =<br>
+      new (Context) SwitchStmt(Context, Cond.get().first, Cond.get().second);<br>
   getCurFunction()->SwitchStack.push_back(SS);<br>
   return SS;<br>
 }<br>
@@ -1242,27 +1216,17 @@ Sema::DiagnoseAssignmentEnum(QualType Ds<br>
     }<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,<br>
-                     Decl *CondVar, Stmt *Body) {<br>
-  ExprResult CondResult(Cond.release());<br>
-<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (CondVar) {<br>
-    ConditionVar = cast<VarDecl>(CondVar);<br>
-    CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);<br>
-    CondResult = ActOnFinishFullExpr(CondResult.get(), WhileLoc);<br>
-    if (CondResult.isInvalid())<br>
-      return StmtError();<br>
-  }<br>
-  Expr *ConditionExpr = CondResult.get();<br>
-  if (!ConditionExpr)<br>
+StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,<br>
+                                Stmt *Body) {<br>
+  if (Cond.isInvalid())<br>
     return StmtError();<br>
-  CheckBreakContinueBinding(ConditionExpr);<br>
<br>
-  if (ConditionExpr &&<br>
-      !Diags.isIgnored(diag::warn_comma_operator, ConditionExpr->getExprLoc()))<br>
-    CommaVisitor(*this).Visit(ConditionExpr);<br>
+  auto CondVal = Cond.get();<br>
+  CheckBreakContinueBinding(CondVal.second);<br>
+<br>
+  if (CondVal.second &&<br>
+      !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))<br>
+    CommaVisitor(*this).Visit(CondVal.second);<br>
<br>
   DiagnoseUnusedExprResult(Body);<br>
<br>
@@ -1270,7 +1234,7 @@ Sema::ActOnWhileStmt(SourceLocation Whil<br>
     getCurCompoundScope().setHasEmptyLoopBodies();<br>
<br>
   return new (Context)<br>
-      WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);<br>
+      WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);<br>
 }<br>
<br>
 StmtResult<br>
@@ -1280,7 +1244,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc,<br>
   assert(Cond && "ActOnDoStmt(): missing expression");<br>
<br>
   CheckBreakContinueBinding(Cond);<br>
-  ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);<br>
+  ExprResult CondResult = CheckBooleanCondition(DoLoc, Cond);<br>
   if (CondResult.isInvalid())<br>
     return StmtError();<br>
   Cond = CondResult.get();<br>
@@ -1644,11 +1608,13 @@ void Sema::CheckBreakContinueBinding(Exp<br>
   }<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
-                   Stmt *First, FullExprArg second, Decl *secondVar,<br>
-                   FullExprArg third,<br>
-                   SourceLocation RParenLoc, Stmt *Body) {<br>
+StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
+                              Stmt *First, ConditionResult Second,<br>
+                              FullExprArg third, SourceLocation RParenLoc,<br>
+                              Stmt *Body) {<br>
+  if (Second.isInvalid())<br>
+    return StmtError();<br>
+<br>
   if (!getLangOpts().CPlusPlus) {<br>
     if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {<br>
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only<br>
@@ -1666,26 +1632,17 @@ Sema::ActOnForStmt(SourceLocation ForLoc<br>
     }<br>
   }<br>
<br>
-  CheckBreakContinueBinding(second.get());<br>
+  CheckBreakContinueBinding(Second.get().second);<br>
   CheckBreakContinueBinding(third.get());<br>
<br>
-  CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);<br>
+  CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),<br>
+                                   Body);<br>
   CheckForRedundantIteration(*this, third.get(), Body);<br>
<br>
-  ExprResult SecondResult(second.release());<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (secondVar) {<br>
-    ConditionVar = cast<VarDecl>(secondVar);<br>
-    SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);<br>
-    SecondResult = ActOnFinishFullExpr(SecondResult.get(), ForLoc);<br>
-    if (SecondResult.isInvalid())<br>
-      return StmtError();<br>
-  }<br>
-<br>
-  if (SecondResult.get() &&<br>
+  if (Second.get().second &&<br>
       !Diags.isIgnored(diag::warn_comma_operator,<br>
-                       SecondResult.get()->getExprLoc()))<br>
-    CommaVisitor(*this).Visit(SecondResult.get());<br>
+                       Second.get().second->getExprLoc()))<br>
+    CommaVisitor(*this).Visit(Second.get().second);<br>
<br>
   Expr *Third  = third.release().getAs<Expr>();<br>
<br>
@@ -1696,8 +1653,9 @@ Sema::ActOnForStmt(SourceLocation ForLoc<br>
   if (isa<NullStmt>(Body))<br>
     getCurCompoundScope().setHasEmptyLoopBodies();<br>
<br>
-  return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,<br>
-                               Third, Body, ForLoc, LParenLoc, RParenLoc);<br>
+  return new (Context)<br>
+      ForStmt(Context, First, Second.get().second, Second.get().first, Third,<br>
+              Body, ForLoc, LParenLoc, RParenLoc);<br>
 }<br>
<br>
 /// In an Objective C collection iteration statement:<br>
@@ -2384,8 +2342,10 @@ Sema::BuildCXXForRangeStmt(SourceLocatio<br>
     // Build and check __begin != __end expression.<br>
     NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,<br>
                            BeginRef.get(), EndRef.get());<br>
-    NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get());<br>
-    NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());<br>
+    if (!NotEqExpr.isInvalid())<br>
+      NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());<br>
+    if (!NotEqExpr.isInvalid())<br>
+      NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());<br>
     if (NotEqExpr.isInvalid()) {<br>
       Diag(RangeLoc, diag::note_for_range_invalid_iterator)<br>
         << RangeLoc << 0 << BeginRangeRef.get()->getType();<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 23 03:41:20 2016<br>
@@ -410,6 +410,14 @@ public:<br>
     return D;<br>
   }<br>
<br>
+  /// \brief Transform the specified condition.<br>
+  ///<br>
+  /// By default, this transforms the variable and expression and rebuilds<br>
+  /// the condition.<br>
+  Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,<br>
+                                           Expr *Expr,<br>
+                                           Sema::ConditionKind Kind);<br>
+<br>
   /// \brief Transform the attributes associated with the given declaration and<br>
   /// place them on the new declaration.<br>
   ///<br>
@@ -1166,10 +1174,9 @@ public:<br>
   ///<br>
   /// By default, performs semantic analysis to build the new statement.<br>
   /// Subclasses may override this routine to provide different behavior.<br>
-  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,<br>
-                           VarDecl *CondVar, Stmt *Then,<br>
-                           SourceLocation ElseLoc, Stmt *Else) {<br>
-    return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);<br>
+  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::ConditionResult Cond,<br>
+                           Stmt *Then, SourceLocation ElseLoc, Stmt *Else) {<br>
+    return getSema().ActOnIfStmt(IfLoc, Cond, Then, ElseLoc, Else);<br>
   }<br>
<br>
   /// \brief Start building a new switch statement.<br>
@@ -1177,9 +1184,8 @@ public:<br>
   /// By default, performs semantic analysis to build the new statement.<br>
   /// Subclasses may override this routine to provide different behavior.<br>
   StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,<br>
-                                    Expr *Cond, VarDecl *CondVar) {<br>
-    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,<br>
-                                            CondVar);<br>
+                                    Sema::ConditionResult Cond) {<br>
+    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond);<br>
   }<br>
<br>
   /// \brief Attach the body to the switch statement.<br>
@@ -1195,9 +1201,9 @@ public:<br>
   ///<br>
   /// By default, performs semantic analysis to build the new statement.<br>
   /// Subclasses may override this routine to provide different behavior.<br>
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond,<br>
-                              VarDecl *CondVar, Stmt *Body) {<br>
-    return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);<br>
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,<br>
+                              Sema::ConditionResult Cond, Stmt *Body) {<br>
+    return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);<br>
   }<br>
<br>
   /// \brief Build a new do-while statement.<br>
@@ -1216,11 +1222,11 @@ public:<br>
   /// By default, performs semantic analysis to build the new statement.<br>
   /// Subclasses may override this routine to provide different behavior.<br>
   StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
-                            Stmt *Init, Sema::FullExprArg Cond,<br>
-                            VarDecl *CondVar, Sema::FullExprArg Inc,<br>
-                            SourceLocation RParenLoc, Stmt *Body) {<br>
+                            Stmt *Init, Sema::ConditionResult Cond,<br>
+                            Sema::FullExprArg Inc, SourceLocation RParenLoc,<br>
+                            Stmt *Body) {<br>
     return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,<br>
-                                  CondVar, Inc, RParenLoc, Body);<br>
+                                  Inc, RParenLoc, Body);<br>
   }<br>
<br>
   /// \brief Build a new goto statement.<br>
@@ -3357,6 +3363,31 @@ bool TreeTransform<Derived>::TransformEx<br>
   return false;<br>
 }<br>
<br>
+template <typename Derived><br>
+Sema::ConditionResult TreeTransform<Derived>::TransformCondition(<br>
+    SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {<br>
+  if (Var) {<br>
+    VarDecl *ConditionVar = cast_or_null<VarDecl>(<br>
+        getDerived().TransformDefinition(Var->getLocation(), Var));<br>
+<br>
+    if (!ConditionVar)<br>
+      return Sema::ConditionError();<br>
+<br>
+    return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);<br>
+  }<br>
+<br>
+  if (Expr) {<br>
+    ExprResult CondExpr = getDerived().TransformExpr(Expr);<br>
+<br>
+    if (CondExpr.isInvalid())<br>
+      return Sema::ConditionError();<br>
+<br>
+    return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind);<br>
+  }<br>
+<br>
+  return Sema::ConditionResult();<br>
+}<br>
+<br>
 template<typename Derived><br>
 NestedNameSpecifierLoc<br>
 TreeTransform<Derived>::TransformNestedNameSpecifierLoc(<br>
@@ -4962,8 +4993,8 @@ bool TreeTransform<Derived>::TransformEx<br>
     if (NoexceptExpr.isInvalid())<br>
       return true;<br>
<br>
-    NoexceptExpr = getSema().CheckBooleanCondition(<br>
-        NoexceptExpr.get(), NoexceptExpr.get()->getLocStart());<br>
+    // FIXME: This is bogus, a noexcept expression is not a condition.<br>
+    NoexceptExpr = getSema().CheckBooleanCondition(Loc, NoexceptExpr.get());<br>
     if (NoexceptExpr.isInvalid())<br>
       return true;<br>
<br>
@@ -6195,35 +6226,10 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {<br>
   // Transform the condition<br>
-  ExprResult Cond;<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (S->getConditionVariable()) {<br>
-    ConditionVar<br>
-      = cast_or_null<VarDecl>(<br>
-                   getDerived().TransformDefinition(<br>
-                                      S->getConditionVariable()->getLocation(),<br>
-                                                    S->getConditionVariable()));<br>
-    if (!ConditionVar)<br>
-      return StmtError();<br>
-  } else {<br>
-    Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-    if (Cond.isInvalid())<br>
-      return StmtError();<br>
-<br>
-    // Convert the condition to a boolean value.<br>
-    if (S->getCond()) {<br>
-      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr, S->getIfLoc(),<br>
-                                                         Cond.get());<br>
-      if (CondE.isInvalid())<br>
-        return StmtError();<br>
-<br>
-      Cond = CondE.get();<br>
-    }<br>
-  }<br>
-<br>
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get(), S->getIfLoc()));<br>
-  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+  Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+      S->getIfLoc(), S->getConditionVariable(), S->getCond(),<br>
+      Sema::ConditionKind::Boolean);<br>
+  if (Cond.isInvalid())<br>
     return StmtError();<br>
<br>
   // Transform the "then" branch.<br>
@@ -6237,14 +6243,12 @@ TreeTransform<Derived>::TransformIfStmt(<br>
     return StmtError();<br>
<br>
   if (!getDerived().AlwaysRebuild() &&<br>
-      FullCond.get() == S->getCond() &&<br>
-      ConditionVar == S->getConditionVariable() &&<br>
+      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
       Then.get() == S->getThen() &&<br>
       Else.get() == S->getElse())<br>
     return S;<br>
<br>
-  return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,<br>
-                                    Then.get(),<br>
+  return getDerived().RebuildIfStmt(S->getIfLoc(), Cond, Then.get(),<br>
                                     S->getElseLoc(), Else.get());<br>
 }<br>
<br>
@@ -6252,27 +6256,15 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {<br>
   // Transform the condition.<br>
-  ExprResult Cond;<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (S->getConditionVariable()) {<br>
-    ConditionVar<br>
-      = cast_or_null<VarDecl>(<br>
-                   getDerived().TransformDefinition(<br>
-                                      S->getConditionVariable()->getLocation(),<br>
-                                                    S->getConditionVariable()));<br>
-    if (!ConditionVar)<br>
-      return StmtError();<br>
-  } else {<br>
-    Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-    if (Cond.isInvalid())<br>
-      return StmtError();<br>
-  }<br>
+  Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+      S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),<br>
+      Sema::ConditionKind::Switch);<br>
+  if (Cond.isInvalid())<br>
+    return StmtError();<br>
<br>
   // Rebuild the switch statement.<br>
   StmtResult Switch<br>
-    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),<br>
-                                          ConditionVar);<br>
+    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond);<br>
   if (Switch.isInvalid())<br>
     return StmtError();<br>
<br>
@@ -6290,36 +6282,10 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {<br>
   // Transform the condition<br>
-  ExprResult Cond;<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (S->getConditionVariable()) {<br>
-    ConditionVar<br>
-      = cast_or_null<VarDecl>(<br>
-                   getDerived().TransformDefinition(<br>
-                                      S->getConditionVariable()->getLocation(),<br>
-                                                    S->getConditionVariable()));<br>
-    if (!ConditionVar)<br>
-      return StmtError();<br>
-  } else {<br>
-    Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-    if (Cond.isInvalid())<br>
-      return StmtError();<br>
-<br>
-    if (S->getCond()) {<br>
-      // Convert the condition to a boolean value.<br>
-      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,<br>
-                                                         S->getWhileLoc(),<br>
-                                                         Cond.get());<br>
-      if (CondE.isInvalid())<br>
-        return StmtError();<br>
-      Cond = CondE;<br>
-    }<br>
-  }<br>
-<br>
-  Sema::FullExprArg FullCond(<br>
-      getSema().MakeFullExpr(Cond.get(), S->getWhileLoc()));<br>
-  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+  Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+      S->getWhileLoc(), S->getConditionVariable(), S->getCond(),<br>
+      Sema::ConditionKind::Boolean);<br>
+  if (Cond.isInvalid())<br>
     return StmtError();<br>
<br>
   // Transform the body<br>
@@ -6328,13 +6294,11 @@ TreeTransform<Derived>::TransformWhileSt<br>
     return StmtError();<br>
<br>
   if (!getDerived().AlwaysRebuild() &&<br>
-      FullCond.get() == S->getCond() &&<br>
-      ConditionVar == S->getConditionVariable() &&<br>
+      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
       Body.get() == S->getBody())<br>
     return Owned(S);<br>
<br>
-  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,<br>
-                                       ConditionVar, Body.get());<br>
+  return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get());<br>
 }<br>
<br>
 template<typename Derived><br>
@@ -6374,37 +6338,10 @@ TreeTransform<Derived>::TransformForStmt<br>
     getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());<br>
<br>
   // Transform the condition<br>
-  ExprResult Cond;<br>
-  VarDecl *ConditionVar = nullptr;<br>
-  if (S->getConditionVariable()) {<br>
-    ConditionVar<br>
-      = cast_or_null<VarDecl>(<br>
-                   getDerived().TransformDefinition(<br>
-                                      S->getConditionVariable()->getLocation(),<br>
-                                                    S->getConditionVariable()));<br>
-    if (!ConditionVar)<br>
-      return StmtError();<br>
-  } else {<br>
-    Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-    if (Cond.isInvalid())<br>
-      return StmtError();<br>
-<br>
-    if (S->getCond()) {<br>
-      // Convert the condition to a boolean value.<br>
-      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,<br>
-                                                         S->getForLoc(),<br>
-                                                         Cond.get());<br>
-      if (CondE.isInvalid())<br>
-        return StmtError();<br>
-<br>
-      Cond = CondE.get();<br>
-    }<br>
-  }<br>
-<br>
-  Sema::FullExprArg FullCond(<br>
-      getSema().MakeFullExpr(Cond.get(), S->getForLoc()));<br>
-  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+  Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+      S->getForLoc(), S->getConditionVariable(), S->getCond(),<br>
+      Sema::ConditionKind::Boolean);<br>
+  if (Cond.isInvalid())<br>
     return StmtError();<br>
<br>
   // Transform the increment<br>
@@ -6423,14 +6360,14 @@ TreeTransform<Derived>::TransformForStmt<br>
<br>
   if (!getDerived().AlwaysRebuild() &&<br>
       Init.get() == S->getInit() &&<br>
-      FullCond.get() == S->getCond() &&<br>
+      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
       Inc.get() == S->getInc() &&<br>
       Body.get() == S->getBody())<br>
     return S;<br>
<br>
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),<br>
-                                     Init.get(), FullCond, ConditionVar,<br>
-                                     FullInc, S->getRParenLoc(), Body.get());<br>
+                                     Init.get(), Cond, FullInc,<br>
+                                     S->getRParenLoc(), Body.get());<br>
 }<br>
<br>
 template<typename Derived><br>
@@ -6924,7 +6861,7 @@ TreeTransform<Derived>::TransformCXXForR<br>
   if (Cond.isInvalid())<br>
     return StmtError();<br>
   if (Cond.get())<br>
-    Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());<br>
+    Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());<br>
   if (Cond.isInvalid())<br>
     return StmtError();<br>
   if (Cond.get())<br>
<br>
Modified: cfe/trunk/test/FixIt/fixit-vexing-parse.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/FixIt/fixit-vexing-parse.cpp (original)<br>
+++ cfe/trunk/test/FixIt/fixit-vexing-parse.cpp Thu Jun 23 03:41:20 2016<br>
@@ -60,7 +60,7 @@ namespace N {<br>
     VO m(int (*p)[4]);<br>
<br>
     // Don't emit warning and fixit because direct initializer is not permitted here.<br>
-    if (int n(int())){} // expected-error {{function type is not allowed here}} expected-error {{condition must have an initializer}}<br>
+    if (int n(int())){} // expected-error {{function type is not allowed here}}<br>
<br>
     // CHECK: fix-it:"{{.*}}":{66:8-66:10}:" = {}"<br>
     U u(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-condition.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-condition.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-condition.cpp Thu Jun 23 03:41:20 2016<br>
@@ -23,9 +23,9 @@ void f() {<br>
<br>
   if (S b(a)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}<br>
<br>
-  if (S b(n)) {} // expected-error {{a function type is not allowed here}} expected-error {{must have an initializer}}<br>
+  if (S b(n)) {} // expected-error {{a function type is not allowed here}}<br>
   if (S b(n) = 0) {} // expected-error {{a function type is not allowed here}}<br>
-  if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}} expected-error {{did you mean '='?}}<br>
+  if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}}<br>
<br>
   S s(a);<br>
   if (S{s}) {} // ok<br>
<br>
Modified: cfe/trunk/test/SemaCXX/crashes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/crashes.cpp Thu Jun 23 03:41:20 2016<br>
@@ -105,8 +105,7 @@ namespace PR9026 {<br>
 namespace PR10270 {<br>
   template<typename T> class C;<br>
   template<typename T> void f() {<br>
-    if (C<T> == 1) // expected-error{{expected unqualified-id}} \<br>
-                   // expected-error{{invalid '==' at end of declaration}}<br>
+    if (C<T> == 1) // expected-error{{expected unqualified-id}}<br>
       return;<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Thu Jun 23 03:41:20 2016<br>
@@ -176,9 +176,9 @@ namespace test4 {<br>
<br>
     // Make sure these don't crash. Better diagnostics would be nice.<br>
     for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}<br>
-    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}<br>
+    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}<br>
     for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}<br>
-    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}<br>
+    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273548&r1=273547&r2=273548&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273548&r1=273547&r2=273548&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a> (original)<br>
+++ cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a> Thu Jun 23 03:41:20 2016<br>
@@ -6,10 +6,8 @@<br>
 void f(NSArray *a) {<br>
     id keys;<br>
     for (int i : a); // expected-error{{selector element type 'int' is not a valid object}}<br>
-    for ((id)2 : a);  // expected-error {{for range declaration must declare a variable}} \<br>
-                      // expected-warning {{expression result unused}}<br>
-    for (2 : a); // expected-error {{for range declaration must declare a variable}} \<br>
-                 // expected-warning {{expression result unused}}<br>
+    for ((id)2 : a);  // expected-error {{for range declaration must declare a variable}}<br>
+    for (2 : a); // expected-error {{for range declaration must declare a variable}}<br>
<br>
   for (id thisKey : keys);<br>
<br>
@@ -65,8 +63,7 @@ int main ()<br>
 @end<br>
 void test2(NSObject<NSFastEnumeration> *collection) {<br>
   Test2 *obj;<br>
-  for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}} \<br>
-                                // expected-warning {{property access result unused - getters should not be used for side effects}}<br>
+  for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}}<br>
   }<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>