summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-02-16 18:36:44 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-02-16 18:36:44 +0000
commitf45c4ab9d7eac20e1cafbe9a4989c52758ac7652 (patch)
treeca150ab92d5915d17f7bb5e8f34c948a9115b360
parentf942b699bfe6d39030317dfa9a8831bf02ad1b50 (diff)
downloadclang-f45c4ab9d7eac20e1cafbe9a4989c52758ac7652.tar.gz
[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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325369 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--lib/Parse/ParseOpenMP.cpp4
-rw-r--r--lib/Parse/ParsePragma.cpp14
-rw-r--r--test/OpenMP/openmp_check.cpp6
4 files changed, 20 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 80644a7de0..e60f3ae64b 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -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<
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index e9f2029fb7..d34fad8fad 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -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:
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 8cbae5f463..e815ea1355 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -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();
diff --git a/test/OpenMP/openmp_check.cpp b/test/OpenMP/openmp_check.cpp
index 14820485c0..cd4706b57e 100644
--- a/test/OpenMP/openmp_check.cpp
+++ b/test/OpenMP/openmp_check.cpp
@@ -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