r273589 - Revert r273548, "Rearrange condition handling so that semantic checks on a condition variable"

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 23 11:11:16 PDT 2016


Author: pcc
Date: Thu Jun 23 13:11:15 2016
New Revision: 273589

URL: http://llvm.org/viewvc/llvm-project?rev=273589&view=rev
Log:
Revert r273548, "Rearrange condition handling so that semantic checks on a condition variable"
as it caused a regression in -Wfor-loop-analysis.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Sema/SemaStmt.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/FixIt/fixit-vexing-parse.cpp
    cfe/trunk/test/Parser/cxx0x-condition.cpp
    cfe/trunk/test/SemaCXX/crashes.cpp
    cfe/trunk/test/SemaCXX/for-range-examples.cpp
    cfe/trunk/test/SemaObjCXX/foreach.mm

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 23 13:11:15 2016
@@ -1588,8 +1588,8 @@ private:
 
   //===--------------------------------------------------------------------===//
   // C++ if/switch/while condition expression.
-  Sema::ConditionResult ParseCXXCondition(SourceLocation Loc,
-                                          Sema::ConditionKind CK);
+  bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,
+                         SourceLocation Loc, bool ConvertToBoolean);
 
   //===--------------------------------------------------------------------===//
   // C++ Coroutines
@@ -1680,9 +1680,10 @@ private:
                                     unsigned ScopeFlags);
   void ParseCompoundStatementLeadingPragmas();
   StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
-  bool ParseParenExprOrCondition(Sema::ConditionResult &CondResult,
+  bool ParseParenExprOrCondition(ExprResult &ExprResult,
+                                 Decl *&DeclResult,
                                  SourceLocation Loc,
-                                 Sema::ConditionKind CK);
+                                 bool ConvertToBoolean);
   StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);
   StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);
   StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 13:11:15 2016
@@ -3298,7 +3298,6 @@ public:
 public:
   class FullExprArg {
   public:
-    FullExprArg() : E(nullptr) { }
     FullExprArg(Sema &actions) : E(nullptr) { }
 
     ExprResult release() {
@@ -3392,23 +3391,27 @@ public:
                                  ArrayRef<const Attr*> Attrs,
                                  Stmt *SubStmt);
 
-  class ConditionResult;
-  StmtResult ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,
-                         Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);
+  StmtResult ActOnIfStmt(SourceLocation IfLoc,
+                         FullExprArg CondVal, Decl *CondVar,
+                         Stmt *ThenVal,
+                         SourceLocation ElseLoc, Stmt *ElseVal);
   StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
-                                    ConditionResult Cond);
+                                            Expr *Cond,
+                                            Decl *CondVar);
   StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
                                            Stmt *Switch, Stmt *Body);
-  StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
-                            Stmt *Body);
+  StmtResult ActOnWhileStmt(SourceLocation WhileLoc,
+                            FullExprArg Cond,
+                            Decl *CondVar, Stmt *Body);
   StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
-                         SourceLocation WhileLoc, SourceLocation CondLParen,
-                         Expr *Cond, SourceLocation CondRParen);
+                                 SourceLocation WhileLoc,
+                                 SourceLocation CondLParen, Expr *Cond,
+                                 SourceLocation CondRParen);
 
   StmtResult ActOnForStmt(SourceLocation ForLoc,
                           SourceLocation LParenLoc,
-                          Stmt *First,
-                          ConditionResult Second,
+                          Stmt *First, FullExprArg Second,
+                          Decl *SecondVar,
                           FullExprArg Third,
                           SourceLocation RParenLoc,
                           Stmt *Body);
@@ -4798,6 +4801,11 @@ public:
                             bool WarnOnNonAbstractTypes,
                             SourceLocation DtorLoc);
 
+  DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
+  ExprResult CheckConditionVariable(VarDecl *ConditionVar,
+                                    SourceLocation StmtLoc,
+                                    bool ConvertToBoolean);
+
   ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,
                                Expr *Operand, SourceLocation RParen);
   ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
@@ -8915,46 +8923,6 @@ public:
   /// type, and if so, emit a note describing what happened.
   void EmitRelatedResultTypeNoteForReturn(QualType destType);
 
-  class ConditionResult {
-    Decl *ConditionVar;
-    FullExprArg Condition;
-    bool Invalid;
-
-    friend class Sema;
-    ConditionResult(Decl *ConditionVar, FullExprArg Condition)
-        : ConditionVar(ConditionVar), Condition(Condition), Invalid(false) {}
-    explicit ConditionResult(bool Invalid)
-        : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid) {}
-
-  public:
-    ConditionResult() : ConditionResult(false) {}
-    bool isInvalid() const { return Invalid; }
-    std::pair<VarDecl *, Expr *> get() const {
-      return std::make_pair(cast_or_null<VarDecl>(ConditionVar),
-                            Condition.get());
-    }
-  };
-  static ConditionResult ConditionError() { return ConditionResult(true); }
-
-  enum class ConditionKind {
-    Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'.
-    Switch   ///< An integral condition for a 'switch' statement.
-  };
-
-  ConditionResult ActOnCondition(Scope *S, SourceLocation Loc,
-                                 Expr *SubExpr, ConditionKind CK);
-
-  ConditionResult ActOnConditionVariable(Decl *ConditionVar,
-                                         SourceLocation StmtLoc,
-                                         ConditionKind CK);
-
-  DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);
-
-  ExprResult CheckConditionVariable(VarDecl *ConditionVar,
-                                    SourceLocation StmtLoc,
-                                    ConditionKind CK);
-  ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond);
-
   /// CheckBooleanCondition - Diagnose problems involving the use of
   /// the given expression as a boolean condition (e.g. in an if
   /// statement).  Also performs the standard function and array
@@ -8963,7 +8931,10 @@ public:
   /// \param Loc - A location associated with the condition, e.g. the
   /// 'if' keyword.
   /// \return true iff there were any errors
-  ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E);
+  ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);
+
+  ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                   Expr *SubExpr);
 
   /// DiagnoseAssignmentAsCondition - Given that an expression is
   /// being used as a boolean condition, warn if it's an assignment.

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jun 23 13:11:15 2016
@@ -3420,11 +3420,10 @@ Parser::tryParseExceptionSpecification(b
     NoexceptExpr = ParseConstantExpression();
     T.consumeClose();
     // The argument must be contextually convertible to bool. We use
-    // CheckBooleanCondition for this purpose.
-    // FIXME: Add a proper Sema entry point for this.
+    // ActOnBooleanCondition for this purpose.
     if (!NoexceptExpr.isInvalid()) {
-      NoexceptExpr =
-          Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());
+      NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,
+                                                   NoexceptExpr.get());
       NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
     } else {
       NoexceptType = EST_None;

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 23 13:11:15 2016
@@ -1726,19 +1726,27 @@ Parser::ParseCXXTypeConstructExpression(
 /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
 ///             '=' assignment-expression
 ///
+/// \param ExprOut if the condition was parsed as an expression, the parsed
+/// expression.
+///
+/// \param DeclOut if the condition was parsed as a declaration, the parsed
+/// declaration.
+///
 /// \param Loc The location of the start of the statement that requires this
 /// condition, e.g., the "for" in a for loop.
 ///
 /// \param ConvertToBoolean Whether the condition expression should be
 /// converted to a boolean value.
 ///
-/// \returns The parsed condition.
-Sema::ConditionResult Parser::ParseCXXCondition(SourceLocation Loc,
-                                                Sema::ConditionKind CK) {
+/// \returns true if there was a parsing, false otherwise.
+bool Parser::ParseCXXCondition(ExprResult &ExprOut,
+                               Decl *&DeclOut,
+                               SourceLocation Loc,
+                               bool ConvertToBoolean) {
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
     cutOffParsing();
-    return Sema::ConditionError();
+    return true;
   }
 
   ParsedAttributesWithRange attrs(AttrFactory);
@@ -1748,11 +1756,16 @@ Sema::ConditionResult Parser::ParseCXXCo
     ProhibitAttributes(attrs);
 
     // Parse the expression.
-    ExprResult Expr = ParseExpression(); // expression
-    if (Expr.isInvalid())
-      return Sema::ConditionError();
-
-    return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK);
+    ExprOut = ParseExpression(); // expression
+    DeclOut = nullptr;
+    if (ExprOut.isInvalid())
+      return true;
+
+    // If required, convert to a boolean value.
+    if (ConvertToBoolean)
+      ExprOut
+        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());
+    return ExprOut.isInvalid();
   }
 
   // type-specifier-seq
@@ -1770,7 +1783,7 @@ Sema::ConditionResult Parser::ParseCXXCo
     ExprResult AsmLabel(ParseSimpleAsm(&Loc));
     if (AsmLabel.isInvalid()) {
       SkipUntil(tok::semi, StopAtSemi);
-      return Sema::ConditionError();
+      return true;
     }
     DeclaratorInfo.setAsmLabel(AsmLabel.get());
     DeclaratorInfo.SetRangeEnd(Loc);
@@ -1782,9 +1795,8 @@ Sema::ConditionResult Parser::ParseCXXCo
   // Type-check the declaration itself.
   DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), 
                                                         DeclaratorInfo);
-  if (Dcl.isInvalid())
-    return Sema::ConditionError();
-  Decl *DeclOut = Dcl.get();
+  DeclOut = Dcl.get();
+  ExprOut = ExprError();
 
   // '=' assignment-expression
   // If a '==' or '+=' is found, suggest a fixit to '='.
@@ -1804,11 +1816,12 @@ Sema::ConditionResult Parser::ParseCXXCo
     SourceLocation LParen = ConsumeParen(), RParen = LParen;
     if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))
       RParen = ConsumeParen();
-    Diag(DeclOut->getLocation(),
+    Diag(DeclOut ? DeclOut->getLocation() : LParen,
          diag::err_expected_init_in_condition_lparen)
       << SourceRange(LParen, RParen);
   } else {
-    Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);
+    Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),
+         diag::err_expected_init_in_condition);
   }
 
   if (!InitExpr.isInvalid())
@@ -1821,7 +1834,8 @@ Sema::ConditionResult Parser::ParseCXXCo
   // (This is currently handled by Sema).
 
   Actions.FinalizeDeclaration(DeclOut);
-  return Actions.ActOnConditionVariable(DeclOut, Loc, CK);
+  
+  return false;
 }
 
 /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Jun 23 13:11:15 2016
@@ -1052,28 +1052,29 @@ StmtResult Parser::ParseCompoundStatemen
 /// should try to recover harder.  It returns false if the condition is
 /// successfully parsed.  Note that a successful parse can still have semantic
 /// errors in the condition.
-bool Parser::ParseParenExprOrCondition(Sema::ConditionResult &Cond,
+bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
+                                       Decl *&DeclResult,
                                        SourceLocation Loc,
-                                       Sema::ConditionKind CK) {
+                                       bool ConvertToBoolean) {
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
 
   if (getLangOpts().CPlusPlus)
-    Cond = ParseCXXCondition(Loc, CK);
+    ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);
   else {
-    ExprResult CondExpr = ParseExpression();
+    ExprResult = ParseExpression();
+    DeclResult = nullptr;
 
     // If required, convert to a boolean value.
-    if (CondExpr.isInvalid())
-      Cond = Sema::ConditionError();
-    else
-      Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK);
+    if (!ExprResult.isInvalid() && ConvertToBoolean)
+      ExprResult
+        = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());
   }
 
   // If the parser was confused by the condition and we don't have a ')', try to
   // recover by skipping ahead to a semi and bailing out.  If condexp is
   // semantically invalid but we have well formed code, keep going.
-  if (Cond.isInvalid() && Tok.isNot(tok::r_paren)) {
+  if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) {
     SkipUntil(tok::semi);
     // Skipping may have stopped if it found the containing ')'.  If so, we can
     // continue parsing the if statement.
@@ -1131,10 +1132,13 @@ StmtResult Parser::ParseIfStatement(Sour
   ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);
 
   // Parse the condition.
-  Sema::ConditionResult Cond;
-  if (ParseParenExprOrCondition(Cond, IfLoc, Sema::ConditionKind::Boolean))
+  ExprResult CondExp;
+  Decl *CondVar = nullptr;
+  if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
     return StmtError();
 
+  FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));
+
   // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
@@ -1217,8 +1221,8 @@ StmtResult Parser::ParseIfStatement(Sour
   if (ElseStmt.isInvalid())
     ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
 
-  return Actions.ActOnIfStmt(IfLoc, Cond, ThenStmt.get(), ElseLoc,
-                             ElseStmt.get());
+  return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),
+                             ElseLoc, ElseStmt.get());
 }
 
 /// ParseSwitchStatement
@@ -1255,11 +1259,13 @@ StmtResult Parser::ParseSwitchStatement(
   ParseScope SwitchScope(this, ScopeFlags);
 
   // Parse the condition.
-  Sema::ConditionResult Cond;
-  if (ParseParenExprOrCondition(Cond, SwitchLoc, Sema::ConditionKind::Switch))
+  ExprResult Cond;
+  Decl *CondVar = nullptr;
+  if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))
     return StmtError();
 
-  StmtResult Switch = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond);
+  StmtResult Switch
+    = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);
 
   if (Switch.isInvalid()) {
     // Skip the switch body.
@@ -1341,10 +1347,13 @@ StmtResult Parser::ParseWhileStatement(S
   ParseScope WhileScope(this, ScopeFlags);
 
   // Parse the condition.
-  Sema::ConditionResult Cond;
-  if (ParseParenExprOrCondition(Cond, WhileLoc, Sema::ConditionKind::Boolean))
+  ExprResult Cond;
+  Decl *CondVar = nullptr;
+  if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
     return StmtError();
 
+  FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));
+
   // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
@@ -1365,10 +1374,10 @@ StmtResult Parser::ParseWhileStatement(S
   InnerScope.Exit();
   WhileScope.Exit();
 
-  if (Cond.isInvalid() || Body.isInvalid())
+  if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())
     return StmtError();
 
-  return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.get());
+  return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());
 }
 
 /// ParseDoStatement
@@ -1526,10 +1535,12 @@ StmtResult Parser::ParseForStatement(Sou
 
   bool ForEach = false, ForRange = false;
   StmtResult FirstPart;
-  Sema::ConditionResult SecondPart;
+  bool SecondPartIsInvalid = false;
+  FullExprArg SecondPart(Actions);
   ExprResult Collection;
   ForRangeInit ForRangeInit;
   FullExprArg ThirdPart(Actions);
+  Decl *SecondVar = nullptr;
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteOrdinaryName(getCurScope(),
@@ -1634,7 +1645,7 @@ StmtResult Parser::ParseForStatement(Sou
       Diag(Tok, diag::err_for_range_expected_decl)
         << FirstPart.get()->getSourceRange();
       SkipUntil(tok::r_paren, StopBeforeMatch);
-      SecondPart = Sema::ConditionError();
+      SecondPartIsInvalid = true;
     } else {
       if (!Value.isInvalid()) {
         Diag(Tok, diag::err_expected_semi_for);
@@ -1649,28 +1660,29 @@ StmtResult Parser::ParseForStatement(Sou
 
   // Parse the second part of the for specifier.
   getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
-  if (!ForEach && !ForRange && !SecondPart.isInvalid()) {
+  if (!ForEach && !ForRange) {
+    assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
     // Parse the second part of the for specifier.
     if (Tok.is(tok::semi)) {  // for (...;;
       // no second part.
     } else if (Tok.is(tok::r_paren)) {
       // missing both semicolons.
     } else {
+      ExprResult Second;
       if (getLangOpts().CPlusPlus)
-        SecondPart = ParseCXXCondition(ForLoc, Sema::ConditionKind::Boolean);
+        ParseCXXCondition(Second, SecondVar, ForLoc, true);
       else {
-        ExprResult SecondExpr = ParseExpression();
-        if (SecondExpr.isInvalid())
-          SecondPart = Sema::ConditionError();
-        else
-          SecondPart =
-              Actions.ActOnCondition(getCurScope(), ForLoc, SecondExpr.get(),
-                                     Sema::ConditionKind::Boolean);
+        Second = ParseExpression();
+        if (!Second.isInvalid())
+          Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc,
+                                                 Second.get());
       }
+      SecondPartIsInvalid = Second.isInvalid();
+      SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);
     }
 
     if (Tok.isNot(tok::semi)) {
-      if (!SecondPart.isInvalid())
+      if (!SecondPartIsInvalid || SecondVar)
         Diag(Tok, diag::err_expected_semi_for);
       else
         // Skip until semicolon or rparen, don't consume it.
@@ -1769,8 +1781,8 @@ StmtResult Parser::ParseForStatement(Sou
     return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
 
   return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
-                              SecondPart, ThirdPart, T.getCloseLocation(),
-                              Body.get());
+                              SecondPart, SecondVar, ThirdPart,
+                              T.getCloseLocation(), Body.get());
 }
 
 /// ParseGotoStatement

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 23 13:11:15 2016
@@ -10092,10 +10092,10 @@ buildSingleCopyAssignRecursively(Sema &S
                                     SizeType, VK_LValue, OK_Ordinary, Loc);
 
   // Construct the loop that copies all elements of this array.
-  return S.ActOnForStmt(
-      Loc, Loc, InitStmt,
-      S.ActOnCondition(nullptr, Loc, Comparison, Sema::ConditionKind::Boolean),
-      S.MakeFullDiscardedValueExpr(Increment), Loc, Copy.get());
+  return S.ActOnForStmt(Loc, Loc, InitStmt, 
+                        S.MakeFullExpr(Comparison),
+                        nullptr, S.MakeFullDiscardedValueExpr(Increment),
+                        Loc, Copy.get());
 }
 
 static StmtResult

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 13:11:15 2016
@@ -14341,7 +14341,7 @@ void Sema::DiagnoseEqualityWithExtraPare
     }
 }
 
-ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E) {
+ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) {
   DiagnoseAssignmentAsCondition(E);
   if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))
     DiagnoseEqualityWithExtraParens(parenE);
@@ -14371,26 +14371,12 @@ ExprResult Sema::CheckBooleanCondition(S
   return E;
 }
 
-Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,
-                                           Expr *SubExpr, ConditionKind CK) {
-  // Empty conditions are valid in for-statements.
+ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                       Expr *SubExpr) {
   if (!SubExpr)
-    return ConditionResult();
+    return ExprError();
 
-  ExprResult Cond;
-  switch (CK) {
-  case ConditionKind::Boolean:
-    Cond = CheckBooleanCondition(Loc, SubExpr);
-    break;
-
-  case ConditionKind::Switch:
-    Cond = CheckSwitchCondition(Loc, SubExpr);
-    break;
-  }
-  if (Cond.isInvalid())
-    return ConditionError();
-
-  return ConditionResult(nullptr, MakeFullExpr(Cond.get(), Loc));
+  return CheckBooleanCondition(SubExpr, Loc);
 }
 
 namespace {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 13:11:15 2016
@@ -3054,21 +3054,11 @@ void Sema::CheckVirtualDtorCall(CXXDestr
   }
 }
 
-Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,
-                                                   SourceLocation StmtLoc,
-                                                   ConditionKind CK) {
-  ExprResult E =
-      CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);
-  if (E.isInvalid())
-    return ConditionError();
-  return ConditionResult(ConditionVar, MakeFullExpr(E.get(), StmtLoc));
-}
-
 /// \brief Check the use of the given variable as a C++ condition in an if,
 /// while, do-while, or switch statement.
 ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
                                         SourceLocation StmtLoc,
-                                        ConditionKind CK) {
+                                        bool ConvertToBoolean) {
   if (ConditionVar->isInvalidDecl())
     return ExprError();
 
@@ -3092,15 +3082,13 @@ ExprResult Sema::CheckConditionVariable(
 
   MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
 
-  switch (CK) {
-  case ConditionKind::Boolean:
-    return CheckBooleanCondition(StmtLoc, Condition.get());
-
-  case ConditionKind::Switch:
-    return CheckSwitchCondition(StmtLoc, Condition.get());
+  if (ConvertToBoolean) {
+    Condition = CheckBooleanCondition(Condition.get(), StmtLoc);
+    if (Condition.isInvalid())
+      return ExprError();
   }
 
-  llvm_unreachable("unexpected condition kind");
+  return Condition;
 }
 
 /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 23 13:11:15 2016
@@ -6826,11 +6826,12 @@ OMPClause *Sema::ActOnOpenMPIfClause(Ope
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
       !Condition->isInstantiationDependent() &&
       !Condition->containsUnexpandedParameterPack()) {
-    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
+    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
+                                           Condition->getExprLoc(), Condition);
     if (Val.isInvalid())
       return nullptr;
 
-    ValExpr = MakeFullExpr(Val.get()).get();
+    ValExpr = Val.get();
   }
 
   return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
@@ -6845,11 +6846,12 @@ OMPClause *Sema::ActOnOpenMPFinalClause(
   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
       !Condition->isInstantiationDependent() &&
       !Condition->containsUnexpandedParameterPack()) {
-    ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
+    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
+                                           Condition->getExprLoc(), Condition);
     if (Val.isInvalid())
       return nullptr;
 
-    ValExpr = MakeFullExpr(Val.get()).get();
+    ValExpr = Val.get();
   }
 
   return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);

Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jun 23 13:11:15 2016
@@ -504,30 +504,39 @@ public:
 }
 
 StmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,
+Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
                   Stmt *thenStmt, SourceLocation ElseLoc,
                   Stmt *elseStmt) {
-  auto CondVal = Cond.get();
-  if (Cond.isInvalid()) {
-    CondVal.first = nullptr;
-    CondVal.second = new (Context)
-        OpaqueValueExpr(SourceLocation(), Context.BoolTy, VK_RValue);
+  ExprResult CondResult(CondVal.release());
+
+  VarDecl *ConditionVar = nullptr;
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
+    CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);
   }
+  Expr *ConditionExpr = CondResult.getAs<Expr>();
+  if (ConditionExpr) {
 
-  if (!Diags.isIgnored(diag::warn_comma_operator,
-                       CondVal.second->getExprLoc()))
-    CommaVisitor(*this).Visit(CondVal.second);
+    if (!Diags.isIgnored(diag::warn_comma_operator,
+                         ConditionExpr->getExprLoc()))
+      CommaVisitor(*this).Visit(ConditionExpr);
 
-  DiagnoseUnusedExprResult(thenStmt);
+    DiagnoseUnusedExprResult(thenStmt);
 
-  if (!elseStmt) {
-    DiagnoseEmptyStmtBody(CondVal.second->getLocEnd(), thenStmt,
-                          diag::warn_empty_if_body);
-  }
+    if (!elseStmt) {
+      DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
+                            diag::warn_empty_if_body);
+    }
 
-  DiagnoseUnusedExprResult(elseStmt);
+    DiagnoseUnusedExprResult(elseStmt);
+  } else {
+    // Create a dummy Expr for the condition for error recovery
+    ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(),
+                                                  Context.BoolTy, VK_RValue);
+  }
 
-  return new (Context) IfStmt(Context, IfLoc, CondVal.first, CondVal.second,
+  return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
                               thenStmt, ElseLoc, elseStmt);
 }
 
@@ -590,7 +599,24 @@ static QualType GetTypeBeforeIntegralPro
   return expr->getType();
 }
 
-ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {
+StmtResult
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
+                             Decl *CondVar) {
+  ExprResult CondResult;
+
+  VarDecl *ConditionVar = nullptr;
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
+    if (CondResult.isInvalid())
+      return StmtError();
+
+    Cond = CondResult.get();
+  }
+
+  if (!Cond)
+    return StmtError();
+
   class SwitchConvertDiagnoser : public ICEConvertDiagnoser {
     Expr *Cond;
 
@@ -638,24 +664,24 @@ ExprResult Sema::CheckSwitchCondition(So
     }
   } SwitchDiagnoser(Cond);
 
-  ExprResult CondResult =
+  CondResult =
       PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
-  if (CondResult.isInvalid())
-    return ExprError();
+  if (CondResult.isInvalid()) return StmtError();
+  Cond = CondResult.get();
 
   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
-  return UsualUnaryConversions(CondResult.get());
-}
+  CondResult = UsualUnaryConversions(Cond);
+  if (CondResult.isInvalid()) return StmtError();
+  Cond = CondResult.get();
 
-StmtResult
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ConditionResult Cond) {
-  if (Cond.isInvalid())
+  CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
+  if (CondResult.isInvalid())
     return StmtError();
+  Cond = CondResult.get();
 
   getCurFunction()->setHasBranchIntoScope();
 
-  SwitchStmt *SS =
-      new (Context) SwitchStmt(Context, Cond.get().first, Cond.get().second);
+  SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
   getCurFunction()->SwitchStack.push_back(SS);
   return SS;
 }
@@ -1216,17 +1242,27 @@ Sema::DiagnoseAssignmentEnum(QualType Ds
     }
 }
 
-StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
-                                Stmt *Body) {
-  if (Cond.isInvalid())
+StmtResult
+Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
+                     Decl *CondVar, Stmt *Body) {
+  ExprResult CondResult(Cond.release());
+
+  VarDecl *ConditionVar = nullptr;
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
+    CondResult = ActOnFinishFullExpr(CondResult.get(), WhileLoc);
+    if (CondResult.isInvalid())
+      return StmtError();
+  }
+  Expr *ConditionExpr = CondResult.get();
+  if (!ConditionExpr)
     return StmtError();
+  CheckBreakContinueBinding(ConditionExpr);
 
-  auto CondVal = Cond.get();
-  CheckBreakContinueBinding(CondVal.second);
-
-  if (CondVal.second &&
-      !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
-    CommaVisitor(*this).Visit(CondVal.second);
+  if (ConditionExpr &&
+      !Diags.isIgnored(diag::warn_comma_operator, ConditionExpr->getExprLoc()))
+    CommaVisitor(*this).Visit(ConditionExpr);
 
   DiagnoseUnusedExprResult(Body);
 
@@ -1234,7 +1270,7 @@ StmtResult Sema::ActOnWhileStmt(SourceLo
     getCurCompoundScope().setHasEmptyLoopBodies();
 
   return new (Context)
-      WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);
+      WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
 }
 
 StmtResult
@@ -1244,7 +1280,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc,
   assert(Cond && "ActOnDoStmt(): missing expression");
 
   CheckBreakContinueBinding(Cond);
-  ExprResult CondResult = CheckBooleanCondition(DoLoc, Cond);
+  ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
   if (CondResult.isInvalid())
     return StmtError();
   Cond = CondResult.get();
@@ -1608,13 +1644,11 @@ void Sema::CheckBreakContinueBinding(Exp
   }
 }
 
-StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
-                              Stmt *First, ConditionResult Second,
-                              FullExprArg third, SourceLocation RParenLoc,
-                              Stmt *Body) {
-  if (Second.isInvalid())
-    return StmtError();
-
+StmtResult
+Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
+                   Stmt *First, FullExprArg second, Decl *secondVar,
+                   FullExprArg third,
+                   SourceLocation RParenLoc, Stmt *Body) {
   if (!getLangOpts().CPlusPlus) {
     if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
@@ -1632,17 +1666,26 @@ StmtResult Sema::ActOnForStmt(SourceLoca
     }
   }
 
-  CheckBreakContinueBinding(Second.get().second);
+  CheckBreakContinueBinding(second.get());
   CheckBreakContinueBinding(third.get());
 
-  CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),
-                                   Body);
+  CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);
   CheckForRedundantIteration(*this, third.get(), Body);
 
-  if (Second.get().second &&
+  ExprResult SecondResult(second.release());
+  VarDecl *ConditionVar = nullptr;
+  if (secondVar) {
+    ConditionVar = cast<VarDecl>(secondVar);
+    SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
+    SecondResult = ActOnFinishFullExpr(SecondResult.get(), ForLoc);
+    if (SecondResult.isInvalid())
+      return StmtError();
+  }
+
+  if (SecondResult.get() &&
       !Diags.isIgnored(diag::warn_comma_operator,
-                       Second.get().second->getExprLoc()))
-    CommaVisitor(*this).Visit(Second.get().second);
+                       SecondResult.get()->getExprLoc()))
+    CommaVisitor(*this).Visit(SecondResult.get());
 
   Expr *Third  = third.release().getAs<Expr>();
 
@@ -1653,9 +1696,8 @@ StmtResult Sema::ActOnForStmt(SourceLoca
   if (isa<NullStmt>(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return new (Context)
-      ForStmt(Context, First, Second.get().second, Second.get().first, Third,
-              Body, ForLoc, LParenLoc, RParenLoc);
+  return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
+                               Third, Body, ForLoc, LParenLoc, RParenLoc);
 }
 
 /// In an Objective C collection iteration statement:
@@ -2342,10 +2384,8 @@ Sema::BuildCXXForRangeStmt(SourceLocatio
     // Build and check __begin != __end expression.
     NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,
                            BeginRef.get(), EndRef.get());
-    if (!NotEqExpr.isInvalid())
-      NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
-    if (!NotEqExpr.isInvalid())
-      NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
+    NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get());
+    NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
     if (NotEqExpr.isInvalid()) {
       Diag(RangeLoc, diag::note_for_range_invalid_iterator)
         << RangeLoc << 0 << BeginRangeRef.get()->getType();

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 23 13:11:15 2016
@@ -410,14 +410,6 @@ public:
     return D;
   }
 
-  /// \brief Transform the specified condition.
-  ///
-  /// By default, this transforms the variable and expression and rebuilds
-  /// the condition.
-  Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
-                                           Expr *Expr,
-                                           Sema::ConditionKind Kind);
-
   /// \brief Transform the attributes associated with the given declaration and
   /// place them on the new declaration.
   ///
@@ -1174,9 +1166,10 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::ConditionResult Cond,
-                           Stmt *Then, SourceLocation ElseLoc, Stmt *Else) {
-    return getSema().ActOnIfStmt(IfLoc, Cond, Then, ElseLoc, Else);
+  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
+                           VarDecl *CondVar, Stmt *Then,
+                           SourceLocation ElseLoc, Stmt *Else) {
+    return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
   }
 
   /// \brief Start building a new switch statement.
@@ -1184,8 +1177,9 @@ public:
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
-                                    Sema::ConditionResult Cond) {
-    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond);
+                                    Expr *Cond, VarDecl *CondVar) {
+    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,
+                                            CondVar);
   }
 
   /// \brief Attach the body to the switch statement.
@@ -1201,9 +1195,9 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
-                              Sema::ConditionResult Cond, Stmt *Body) {
-    return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond,
+                              VarDecl *CondVar, Stmt *Body) {
+    return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);
   }
 
   /// \brief Build a new do-while statement.
@@ -1222,11 +1216,11 @@ public:
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
-                            Stmt *Init, Sema::ConditionResult Cond,
-                            Sema::FullExprArg Inc, SourceLocation RParenLoc,
-                            Stmt *Body) {
+                            Stmt *Init, Sema::FullExprArg Cond,
+                            VarDecl *CondVar, Sema::FullExprArg Inc,
+                            SourceLocation RParenLoc, Stmt *Body) {
     return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
-                                  Inc, RParenLoc, Body);
+                                  CondVar, Inc, RParenLoc, Body);
   }
 
   /// \brief Build a new goto statement.
@@ -3363,31 +3357,6 @@ bool TreeTransform<Derived>::TransformEx
   return false;
 }
 
-template <typename Derived>
-Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
-    SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
-  if (Var) {
-    VarDecl *ConditionVar = cast_or_null<VarDecl>(
-        getDerived().TransformDefinition(Var->getLocation(), Var));
-
-    if (!ConditionVar)
-      return Sema::ConditionError();
-
-    return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
-  }
-
-  if (Expr) {
-    ExprResult CondExpr = getDerived().TransformExpr(Expr);
-
-    if (CondExpr.isInvalid())
-      return Sema::ConditionError();
-
-    return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind);
-  }
-
-  return Sema::ConditionResult();
-}
-
 template<typename Derived>
 NestedNameSpecifierLoc
 TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
@@ -4993,8 +4962,8 @@ bool TreeTransform<Derived>::TransformEx
     if (NoexceptExpr.isInvalid())
       return true;
 
-    // FIXME: This is bogus, a noexcept expression is not a condition.
-    NoexceptExpr = getSema().CheckBooleanCondition(Loc, NoexceptExpr.get());
+    NoexceptExpr = getSema().CheckBooleanCondition(
+        NoexceptExpr.get(), NoexceptExpr.get()->getLocStart());
     if (NoexceptExpr.isInvalid())
       return true;
 
@@ -6226,10 +6195,35 @@ template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
   // Transform the condition
-  Sema::ConditionResult Cond = getDerived().TransformCondition(
-      S->getIfLoc(), S->getConditionVariable(), S->getCond(),
-      Sema::ConditionKind::Boolean);
-  if (Cond.isInvalid())
+  ExprResult Cond;
+  VarDecl *ConditionVar = nullptr;
+  if (S->getConditionVariable()) {
+    ConditionVar
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+
+    if (Cond.isInvalid())
+      return StmtError();
+
+    // Convert the condition to a boolean value.
+    if (S->getCond()) {
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr, S->getIfLoc(),
+                                                         Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+
+      Cond = CondE.get();
+    }
+  }
+
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get(), S->getIfLoc()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
   // Transform the "then" branch.
@@ -6243,12 +6237,14 @@ TreeTransform<Derived>::TransformIfStmt(
     return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
+      FullCond.get() == S->getCond() &&
+      ConditionVar == S->getConditionVariable() &&
       Then.get() == S->getThen() &&
       Else.get() == S->getElse())
     return S;
 
-  return getDerived().RebuildIfStmt(S->getIfLoc(), Cond, Then.get(),
+  return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
+                                    Then.get(),
                                     S->getElseLoc(), Else.get());
 }
 
@@ -6256,15 +6252,27 @@ template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
   // Transform the condition.
-  Sema::ConditionResult Cond = getDerived().TransformCondition(
-      S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
-      Sema::ConditionKind::Switch);
-  if (Cond.isInvalid())
-    return StmtError();
+  ExprResult Cond;
+  VarDecl *ConditionVar = nullptr;
+  if (S->getConditionVariable()) {
+    ConditionVar
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+
+    if (Cond.isInvalid())
+      return StmtError();
+  }
 
   // Rebuild the switch statement.
   StmtResult Switch
-    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond);
+    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
+                                          ConditionVar);
   if (Switch.isInvalid())
     return StmtError();
 
@@ -6282,10 +6290,36 @@ template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
   // Transform the condition
-  Sema::ConditionResult Cond = getDerived().TransformCondition(
-      S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
-      Sema::ConditionKind::Boolean);
-  if (Cond.isInvalid())
+  ExprResult Cond;
+  VarDecl *ConditionVar = nullptr;
+  if (S->getConditionVariable()) {
+    ConditionVar
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+
+    if (Cond.isInvalid())
+      return StmtError();
+
+    if (S->getCond()) {
+      // Convert the condition to a boolean value.
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
+                                                         S->getWhileLoc(),
+                                                         Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+      Cond = CondE;
+    }
+  }
+
+  Sema::FullExprArg FullCond(
+      getSema().MakeFullExpr(Cond.get(), S->getWhileLoc()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
   // Transform the body
@@ -6294,11 +6328,13 @@ TreeTransform<Derived>::TransformWhileSt
     return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
+      FullCond.get() == S->getCond() &&
+      ConditionVar == S->getConditionVariable() &&
       Body.get() == S->getBody())
     return Owned(S);
 
-  return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get());
+  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
+                                       ConditionVar, Body.get());
 }
 
 template<typename Derived>
@@ -6338,10 +6374,37 @@ TreeTransform<Derived>::TransformForStmt
     getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
 
   // Transform the condition
-  Sema::ConditionResult Cond = getDerived().TransformCondition(
-      S->getForLoc(), S->getConditionVariable(), S->getCond(),
-      Sema::ConditionKind::Boolean);
-  if (Cond.isInvalid())
+  ExprResult Cond;
+  VarDecl *ConditionVar = nullptr;
+  if (S->getConditionVariable()) {
+    ConditionVar
+      = cast_or_null<VarDecl>(
+                   getDerived().TransformDefinition(
+                                      S->getConditionVariable()->getLocation(),
+                                                    S->getConditionVariable()));
+    if (!ConditionVar)
+      return StmtError();
+  } else {
+    Cond = getDerived().TransformExpr(S->getCond());
+
+    if (Cond.isInvalid())
+      return StmtError();
+
+    if (S->getCond()) {
+      // Convert the condition to a boolean value.
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
+                                                         S->getForLoc(),
+                                                         Cond.get());
+      if (CondE.isInvalid())
+        return StmtError();
+
+      Cond = CondE.get();
+    }
+  }
+
+  Sema::FullExprArg FullCond(
+      getSema().MakeFullExpr(Cond.get(), S->getForLoc()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
   // Transform the increment
@@ -6360,14 +6423,14 @@ TreeTransform<Derived>::TransformForStmt
 
   if (!getDerived().AlwaysRebuild() &&
       Init.get() == S->getInit() &&
-      Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
+      FullCond.get() == S->getCond() &&
       Inc.get() == S->getInc() &&
       Body.get() == S->getBody())
     return S;
 
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
-                                     Init.get(), Cond, FullInc,
-                                     S->getRParenLoc(), Body.get());
+                                     Init.get(), FullCond, ConditionVar,
+                                     FullInc, S->getRParenLoc(), Body.get());
 }
 
 template<typename Derived>
@@ -6861,7 +6924,7 @@ TreeTransform<Derived>::TransformCXXForR
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())
-    Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
+    Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())

Modified: cfe/trunk/test/FixIt/fixit-vexing-parse.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-vexing-parse.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-vexing-parse.cpp Thu Jun 23 13:11:15 2016
@@ -60,7 +60,7 @@ namespace N {
     VO m(int (*p)[4]);
 
     // Don't emit warning and fixit because direct initializer is not permitted here.
-    if (int n(int())){} // expected-error {{function type is not allowed here}}
+    if (int n(int())){} // expected-error {{function type is not allowed here}} expected-error {{condition must have an initializer}}
 
     // CHECK: fix-it:"{{.*}}":{66:8-66:10}:" = {}"
     U u(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}

Modified: cfe/trunk/test/Parser/cxx0x-condition.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-condition.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-condition.cpp Thu Jun 23 13:11:15 2016
@@ -23,9 +23,9 @@ void f() {
 
   if (S b(a)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}
 
-  if (S b(n)) {} // expected-error {{a function type is not allowed here}}
+  if (S b(n)) {} // expected-error {{a function type is not allowed here}} expected-error {{must have an initializer}}
   if (S b(n) = 0) {} // expected-error {{a function type is not allowed here}}
-  if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}}
+  if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}} expected-error {{did you mean '='?}}
 
   S s(a);
   if (S{s}) {} // ok

Modified: cfe/trunk/test/SemaCXX/crashes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)
+++ cfe/trunk/test/SemaCXX/crashes.cpp Thu Jun 23 13:11:15 2016
@@ -105,7 +105,8 @@ namespace PR9026 {
 namespace PR10270 {
   template<typename T> class C;
   template<typename T> void f() {
-    if (C<T> == 1) // expected-error{{expected unqualified-id}}
+    if (C<T> == 1) // expected-error{{expected unqualified-id}} \
+                   // expected-error{{invalid '==' at end of declaration}}
       return;
   }
 }

Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Thu Jun 23 13:11:15 2016
@@ -176,9 +176,9 @@ namespace test4 {
 
     // Make sure these don't crash. Better diagnostics would be nice.
     for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
-    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}
+    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
     for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
-    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}
+    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
   }
 }
 

Modified: cfe/trunk/test/SemaObjCXX/foreach.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273589&r1=273588&r2=273589&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/foreach.mm (original)
+++ cfe/trunk/test/SemaObjCXX/foreach.mm Thu Jun 23 13:11:15 2016
@@ -6,8 +6,10 @@
 void f(NSArray *a) {
     id keys;
     for (int i : a); // expected-error{{selector element type 'int' is not a valid object}} 
-    for ((id)2 : a);  // expected-error {{for range declaration must declare a variable}}
-    for (2 : a); // expected-error {{for range declaration must declare a variable}}
+    for ((id)2 : a);  // expected-error {{for range declaration must declare a variable}} \
+                      // expected-warning {{expression result unused}}
+    for (2 : a); // expected-error {{for range declaration must declare a variable}} \
+                 // expected-warning {{expression result unused}}
   
   for (id thisKey : keys);
 
@@ -63,7 +65,8 @@ int main ()
 @end
 void test2(NSObject<NSFastEnumeration> *collection) {
   Test2 *obj;
-  for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}}
+  for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}} \
+                                // expected-warning {{property access result unused - getters should not be used for side effects}}
   }
 }
 




More information about the cfe-commits mailing list