diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-23 19:02:52 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-23 19:02:52 +0000 |
commit | a64a49776e41ee8edeb24caf928e489f7b1df0e5 (patch) | |
tree | 6b775601632fc52f916af0ee057604c7d1e0fede /lib/Parse/ParseExprCXX.cpp | |
parent | c4e95c76197d386452a9b4524a4a5429b32bce72 (diff) |
Re-commit r273548, reverted in r273589, with a fix to not produce
-Wfor-loop-analysis warnings for a for-loop with a condition variable. In such
a case, the loop condition variable is modified on each iteration of the loop
by definition.
Original commit message:
Rearrange condition handling so that semantic checks on a condition variable
are performed before the other substatements of the construct are parsed,
rather than deferring them until the end. This allows better error recovery
from semantic errors in the condition, improves diagnostic order, and is a
prerequisite for C++17 constexpr if.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273600 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 44 |
1 files changed, 15 insertions, 29 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index b0740970d8..00f20e5e7b 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1726,27 +1726,19 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { /// [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 true if there was a parsing, false otherwise. -bool Parser::ParseCXXCondition(ExprResult &ExprOut, - Decl *&DeclOut, - SourceLocation Loc, - bool ConvertToBoolean) { +/// \returns The parsed condition. +Sema::ConditionResult Parser::ParseCXXCondition(SourceLocation Loc, + Sema::ConditionKind CK) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); cutOffParsing(); - return true; + return Sema::ConditionError(); } ParsedAttributesWithRange attrs(AttrFactory); @@ -1756,16 +1748,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut, ProhibitAttributes(attrs); // Parse the expression. - ExprOut = ParseExpression(); // expression - DeclOut = nullptr; - if (ExprOut.isInvalid()) - return true; + ExprResult Expr = ParseExpression(); // expression + if (Expr.isInvalid()) + return Sema::ConditionError(); - // If required, convert to a boolean value. - if (ConvertToBoolean) - ExprOut - = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get()); - return ExprOut.isInvalid(); + return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK); } // type-specifier-seq @@ -1783,7 +1770,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut, ExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) { SkipUntil(tok::semi, StopAtSemi); - return true; + return Sema::ConditionError(); } DeclaratorInfo.setAsmLabel(AsmLabel.get()); DeclaratorInfo.SetRangeEnd(Loc); @@ -1795,8 +1782,9 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut, // Type-check the declaration itself. DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), DeclaratorInfo); - DeclOut = Dcl.get(); - ExprOut = ExprError(); + if (Dcl.isInvalid()) + return Sema::ConditionError(); + Decl *DeclOut = Dcl.get(); // '=' assignment-expression // If a '==' or '+=' is found, suggest a fixit to '='. @@ -1816,12 +1804,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut, SourceLocation LParen = ConsumeParen(), RParen = LParen; if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) RParen = ConsumeParen(); - Diag(DeclOut ? DeclOut->getLocation() : LParen, + Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition_lparen) << SourceRange(LParen, RParen); } else { - Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(), - diag::err_expected_init_in_condition); + Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition); } if (!InitExpr.isInvalid()) @@ -1834,8 +1821,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut, // (This is currently handled by Sema). Actions.FinalizeDeclaration(DeclOut); - - return false; + return Actions.ActOnConditionVariable(DeclOut, Loc, CK); } /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers. |