<div dir="ltr">Thanks!</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 23, 2016 at 12:02 PM, 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 14:02:52 2016<br>
New Revision: 273600<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=273600&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=273600&view=rev</a><br>
Log:<br>
Re-commit r273548, reverted in r273589, with a fix to not produce<br>
-Wfor-loop-analysis warnings for a for-loop with a condition variable. In such<br>
a case, the loop condition variable is modified on each iteration of the loop<br>
by definition.<br>
<br>
Original commit message:<br>
<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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jun 23 14:02:52 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,18 @@ 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>
+  if (!Second.get().first)<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 +1654,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 +2343,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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273600&r1=273599&r2=273600&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 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-condition.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-condition.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/crashes.cpp Thu Jun 23 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273600&r1=273599&r2=273600&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 14:02:52 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=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273600&r1=273599&r2=273600&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 14:02:52 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><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">-- <div>Peter</div></div></div>
</div>