summaryrefslogtreecommitdiff
path: root/clang/lib/Parse/ParseStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseStmt.cpp')
-rw-r--r--clang/lib/Parse/ParseStmt.cpp53
1 files changed, 43 insertions, 10 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 0339328ca5137..89a6a2b829ae1 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -105,6 +105,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts,
StmtResult Res = ParseStatementOrDeclarationAfterAttributes(
Stmts, StmtCtx, TrailingElseLoc, Attrs);
+ MaybeDestroyTemplateIds();
assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) &&
"attributes on empty statement");
@@ -353,13 +354,13 @@ Retry:
case tok::annot_pragma_fp_contract:
ProhibitAttributes(Attrs);
- Diag(Tok, diag::err_pragma_fp_contract_scope);
+ Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract";
ConsumeAnnotationToken();
return StmtError();
case tok::annot_pragma_fp:
ProhibitAttributes(Attrs);
- Diag(Tok, diag::err_pragma_fp_scope);
+ Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp";
ConsumeAnnotationToken();
return StmtError();
@@ -368,6 +369,12 @@ Retry:
HandlePragmaFEnvAccess();
return StmtEmpty();
+ case tok::annot_pragma_float_control:
+ ProhibitAttributes(Attrs);
+ Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control";
+ ConsumeAnnotationToken();
+ return StmtError();
+
case tok::annot_pragma_opencl_extension:
ProhibitAttributes(Attrs);
HandlePragmaOpenCLExtension();
@@ -936,6 +943,9 @@ void Parser::ParseCompoundStatementLeadingPragmas() {
case tok::annot_pragma_fenv_access:
HandlePragmaFEnvAccess();
break;
+ case tok::annot_pragma_float_control:
+ HandlePragmaFloatControl();
+ break;
case tok::annot_pragma_ms_pointers_to_members:
HandlePragmaMSPointersToMembers();
break;
@@ -1014,9 +1024,9 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
Tok.getLocation(),
"in compound statement ('{}')");
- // Record the state of the FP_CONTRACT pragma, restore on leaving the
+ // Record the state of the FPFeatures, restore on leaving the
// compound statement.
- Sema::FPContractStateRAII SaveFPContractState(Actions);
+ Sema::FPFeaturesStateRAII SaveFPContractState(Actions);
InMessageExpressionRAIIObject InMessage(*this, false);
BalancedDelimiterTracker T(*this, tok::l_brace);
@@ -1146,10 +1156,14 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
/// 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.
+/// Additionally, if LParenLoc and RParenLoc are non-null, it will assign
+/// the location of the outer-most '(' and ')', respectively, to them.
bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
Sema::ConditionResult &Cond,
SourceLocation Loc,
- Sema::ConditionKind CK) {
+ Sema::ConditionKind CK,
+ SourceLocation *LParenLoc,
+ SourceLocation *RParenLoc) {
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
@@ -1179,6 +1193,13 @@ bool Parser::ParseParenExprOrCondition(StmtResult *InitStmt,
// Otherwise the condition is valid or the rparen is present.
T.consumeClose();
+ if (LParenLoc != nullptr) {
+ *LParenLoc = T.getOpenLocation();
+ }
+ if (RParenLoc != nullptr) {
+ *RParenLoc = T.getCloseLocation();
+ }
+
// Check for extraneous ')'s to catch things like "if (foo())) {". We know
// that all callers are looking for a statement after the condition, so ")"
// isn't valid.
@@ -1338,6 +1359,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
if (IsConstexpr)
ConstexprCondition = Cond.getKnownValue();
+ bool IsBracedThen = Tok.is(tok::l_brace);
+
// 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.
@@ -1356,7 +1379,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// would have to notify ParseStatement not to create a new scope. It's
// simpler to let it create a new scope.
//
- ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
+ ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
@@ -1417,7 +1440,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// Pop the 'else' scope if needed.
InnerScope.Exit();
} else if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteAfterIf(getCurScope());
+ Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
cutOffParsing();
return StmtError();
} else if (InnerStatementTrailingElseLoc.isValid()) {
@@ -1570,8 +1593,10 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
// Parse the condition.
Sema::ConditionResult Cond;
+ SourceLocation LParen;
+ SourceLocation RParen;
if (ParseParenExprOrCondition(nullptr, Cond, WhileLoc,
- Sema::ConditionKind::Boolean))
+ Sema::ConditionKind::Boolean, &LParen, &RParen))
return StmtError();
// C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
@@ -1601,7 +1626,7 @@ StmtResult Parser::ParseWhileStatement(SourceLocation *TrailingElseLoc) {
if (Cond.isInvalid() || Body.isInvalid())
return StmtError();
- return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.get());
+ return Actions.ActOnWhileStmt(WhileLoc, LParen, Cond, RParen, Body.get());
}
/// ParseDoStatement
@@ -1921,7 +1946,7 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
if (ForRangeInfo.ParsedForRangeDecl()) {
Diag(FirstPart.get() ? FirstPart.get()->getBeginLoc()
: ForRangeInfo.ColonLoc,
- getLangOpts().CPlusPlus2a
+ getLangOpts().CPlusPlus20
? diag::warn_cxx17_compat_for_range_init_stmt
: diag::ext_for_range_init_stmt)
<< (FirstPart.get() ? FirstPart.get()->getSourceRange()
@@ -2162,6 +2187,8 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
// Create temporary attribute list.
ParsedAttributesWithRange TempAttrs(AttrFactory);
+ SourceLocation StartLoc = Tok.getLocation();
+
// Get loop hints and consume annotated token.
while (Tok.is(tok::annot_pragma_loop_hint)) {
LoopHint Hint;
@@ -2182,6 +2209,12 @@ StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts,
Stmts, StmtCtx, TrailingElseLoc, Attrs);
Attrs.takeAllFrom(TempAttrs);
+
+ // Start of attribute range may already be set for some invalid input.
+ // See PR46336.
+ if (Attrs.Range.getBegin().isInvalid())
+ Attrs.Range.setBegin(StartLoc);
+
return S;
}