[OPENMP] Fix parsing of the directives with inner directives.
authorAlexey Bataev <a.bataev@hotmail.com>
Fri, 16 Feb 2018 18:36:44 +0000 (18:36 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Fri, 16 Feb 2018 18:36:44 +0000 (18:36 +0000)
The parsing may lead to compiler hanging because of the incorrect
processing of inner OpenMP pragmas.

llvm-svn: 325369

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Parse/ParsePragma.cpp
clang/test/OpenMP/openmp_check.cpp

index 80644a7..e60f3ae 100644 (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<
index e9f2029..d34fad8 100644 (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:
index 8cbae5f..e815ea1 100644 (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();
index 1482048..cd4706b 100644 (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