[OPENMP] Fix parsing of the directives with inner directives.

The parsing may lead to compiler hanging because of the incorrect
processing of inner OpenMP pragmas.

llvm-svn: 325369
This commit is contained in:
Alexey Bataev 2018-02-16 18:36:44 +00:00
parent 79bd39db80
commit 96dae81d7f
4 changed files with 20 additions and 6 deletions

View File

@ -1072,7 +1072,7 @@ def warn_pragma_expected_colon_r_paren : Warning<
def err_omp_unknown_directive : Error<
"expected an OpenMP directive">;
def err_omp_unexpected_directive : Error<
"unexpected OpenMP directive '#pragma omp %0'">;
"unexpected OpenMP directive %select{|'#pragma omp %1'}0">;
def err_omp_expected_punc : Error<
"expected ',' or ')' in '%0' %select{clause|directive}1">;
def err_omp_unexpected_clause : Error<

View File

@ -851,7 +851,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
case OMPD_target_teams_distribute_parallel_for_simd:
case OMPD_target_teams_distribute_simd:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
<< 1 << getOpenMPDirectiveName(DKind);
break;
}
while (Tok.isNot(tok::annot_pragma_openmp_end))
@ -1107,7 +1107,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_declare_target:
case OMPD_end_declare_target:
Diag(Tok, diag::err_omp_unexpected_directive)
<< getOpenMPDirectiveName(DKind);
<< 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
break;
case OMPD_unknown:

View File

@ -2117,9 +2117,21 @@ PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
Tok.setKind(tok::annot_pragma_openmp);
Tok.setLocation(FirstTok.getLocation());
while (Tok.isNot(tok::eod)) {
while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
Pragma.push_back(Tok);
PP.Lex(Tok);
if (Tok.is(tok::annot_pragma_openmp)) {
PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
unsigned InnerPragmaCnt = 1;
while (InnerPragmaCnt != 0) {
PP.Lex(Tok);
if (Tok.is(tok::annot_pragma_openmp))
++InnerPragmaCnt;
else if (Tok.is(tok::annot_pragma_openmp_end))
--InnerPragmaCnt;
}
PP.Lex(Tok);
}
}
SourceLocation EodLoc = Tok.getLocation();
Tok.startToken();

View File

@ -7,7 +7,11 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 %s
// SIMD-ONLY0-NOT: {{__kmpc|__tgt}}
#define p _Pragma("omp parallel")
int nested(int a) {
#pragma omp parallel p // expected-error {{unexpected OpenMP directive}}
++a;
#pragma omp parallel
++a;
@ -16,8 +20,6 @@ int nested(int a) {
// expected-warning@-2 {{'auto' type specifier is a C++11 extension}}
// expected-error@-3 {{expected expression}}
// expected-error@-4 {{expected ';' at end of declaration}}
#else
// expected-no-diagnostics
#endif
#pragma omp parallel