diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index bfe5061481ad9..1fee9f82b3e6a 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -784,29 +784,37 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, ExprResult CondExpr = ParseOpenACCConditionalExpr(*this); // An invalid expression can be just about anything, so just give up on // this clause list. - if (CondExpr.isInvalid()) - return true; + if (CondExpr.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::CopyIn: tryParseAndConsumeSpecialTokenKind( *this, OpenACCSpecialTokenKind::ReadOnly, Kind); - if (ParseOpenACCClauseVarList(Kind)) - return true; + if (ParseOpenACCClauseVarList(Kind)) { + Parens.skipToEnd(); + return false; + } break; case OpenACCClauseKind::Create: case OpenACCClauseKind::CopyOut: tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Zero, Kind); - if (ParseOpenACCClauseVarList(Kind)) - return true; + if (ParseOpenACCClauseVarList(Kind)) { + Parens.skipToEnd(); + return false; + } break; case OpenACCClauseKind::Reduction: // If we're missing a clause-kind (or it is invalid), see if we can parse // the var-list anyway. ParseReductionOperator(*this); - if (ParseOpenACCClauseVarList(Kind)) - return true; + if (ParseOpenACCClauseVarList(Kind)) { + Parens.skipToEnd(); + return false; + } break; case OpenACCClauseKind::Self: // The 'self' clause is a var-list instead of a 'condition' in the case of @@ -828,22 +836,28 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, case OpenACCClauseKind::Present: case OpenACCClauseKind::Private: case OpenACCClauseKind::UseDevice: - if (ParseOpenACCClauseVarList(Kind)) - return true; + if (ParseOpenACCClauseVarList(Kind)) { + Parens.skipToEnd(); + return false; + } break; case OpenACCClauseKind::Collapse: { tryParseAndConsumeSpecialTokenKind(*this, OpenACCSpecialTokenKind::Force, Kind); ExprResult NumLoops = getActions().CorrectDelayedTyposInExpr(ParseConstantExpression()); - if (NumLoops.isInvalid()) - return true; + if (NumLoops.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::Bind: { ExprResult BindArg = ParseOpenACCBindClauseArgument(); - if (BindArg.isInvalid()) - return true; + if (BindArg.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::NumGangs: @@ -852,8 +866,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, case OpenACCClauseKind::DefaultAsync: case OpenACCClauseKind::VectorLength: { ExprResult IntExpr = ParseOpenACCIntExpr(); - if (IntExpr.isInvalid()) - return true; + if (IntExpr.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::DType: @@ -863,12 +879,15 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, // device_type in Sema. ConsumeToken(); } else if (ParseOpenACCDeviceTypeList()) { - return true; + Parens.skipToEnd(); + return false; } break; case OpenACCClauseKind::Tile: - if (ParseOpenACCSizeExprList()) - return true; + if (ParseOpenACCSizeExprList()) { + Parens.skipToEnd(); + return false; + } break; default: llvm_unreachable("Not a required parens type?"); @@ -883,8 +902,10 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, ExprResult CondExpr = ParseOpenACCConditionalExpr(*this); // An invalid expression can be just about anything, so just give up on // this clause list. - if (CondExpr.isInvalid()) - return true; + if (CondExpr.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::Vector: @@ -895,19 +916,25 @@ bool Parser::ParseOpenACCClauseParams(OpenACCDirectiveKind DirKind, : OpenACCSpecialTokenKind::Num, Kind); ExprResult IntExpr = ParseOpenACCIntExpr(); - if (IntExpr.isInvalid()) - return true; + if (IntExpr.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::Async: { ExprResult AsyncArg = ParseOpenACCAsyncArgument(); - if (AsyncArg.isInvalid()) - return true; + if (AsyncArg.isInvalid()) { + Parens.skipToEnd(); + return false; + } break; } case OpenACCClauseKind::Gang: - if (ParseOpenACCGangArgList()) - return true; + if (ParseOpenACCGangArgList()) { + Parens.skipToEnd(); + return false; + } break; case OpenACCClauseKind::Wait: if (ParseOpenACCWaitArgument()) { diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index c7a8f4b23509c..18eb0fc996cce 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -205,18 +205,24 @@ void IfClause() { #pragma acc serial if, seq for(;;){} - // expected-error@+2{{expected expression}} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial if( for(;;){} - // expected-error@+2{{use of undeclared identifier 'seq'}} + // expected-error@+4{{use of undeclared identifier 'seq'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial if( seq for(;;){} - // expected-error@+3{{expected expression}} - // expected-error@+2{{use of undeclared identifier 'seq'}} + // expected-error@+5{{expected expression}} + // expected-error@+4{{use of undeclared identifier 'seq'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial if(, seq for(;;){} @@ -284,18 +290,24 @@ void SyncClause() { #pragma acc serial loop self, seq for(;;){} - // expected-error@+2{{expected expression}} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial loop self( for(;;){} - // expected-error@+2{{use of undeclared identifier 'seq'}} + // expected-error@+4{{use of undeclared identifier 'seq'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial loop self( seq for(;;){} - // expected-error@+3{{expected expression}} - // expected-error@+2{{use of undeclared identifier 'seq'}} + // expected-error@+5{{expected expression}} + // expected-error@+4{{use of undeclared identifier 'seq'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial loop self(, seq for(;;){} @@ -340,7 +352,9 @@ void SyncClause() { #pragma acc serial self(i > j for(;;){} - // expected-error@+2{{use of undeclared identifier 'seq'}} + // expected-error@+4{{use of undeclared identifier 'seq'}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial self(i > j, seq for(;;){} @@ -405,11 +419,15 @@ void VarListClauses() { // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial copy), seq - // expected-error@+2{{expected expression}} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial copy( - // expected-error@+2{{expected expression}} + // expected-error@+4{{expected expression}} + // expected-error@+3{{expected ')'}} + // expected-note@+2{{to match this '('}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc serial copy(, seq