Author: Aaron Ballman
Date: 2025-05-14T10:19:24-04:00
New Revision: 0eb8a92ce9a55059b06bf456b53971bb62246a9f

URL: 
https://github.com/llvm/llvm-project/commit/0eb8a92ce9a55059b06bf456b53971bb62246a9f
DIFF: 
https://github.com/llvm/llvm-project/commit/0eb8a92ce9a55059b06bf456b53971bb62246a9f.diff

LOG: [OpenMP] Fix tentative parsing crash with metadirective (#139901)

There were two crashes that have the same root cause: not correctly
handling unexpected tokens. In one case, we were failing to return early
which caused us to parse a paren as a regular token instead of a special
token, causing an assertion. The other case was failing to commit or
revert the tentative parse action when not getting a paren when one was
expected.

Fixes #139665

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseOpenMP.cpp
    clang/test/OpenMP/metadirective_messages.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 81cf369fe4440..191cb5e95f125 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -946,6 +946,10 @@ OpenMP Support
 - Fixed a crashing bug with a malformed ``cancel`` directive. (#GH139360)
 - Fixed a crashing bug with ``omp distribute dist_schedule`` if the argument to
   ``dist_schedule`` was not strictly positive. (#GH139266)
+- Fixed two crashing bugs with a malformed ``metadirective`` directive. One was
+  a crash if the next token after ``metadirective`` was a paren, bracket, or
+  brace. The other was if the next token after the meta directive was not an
+  open parenthesis. (#GH139665)
 
 Improvements
 ^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index c409409602e75..d7840d97e8d9b 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2666,8 +2666,12 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
                                    ? OMPC_unknown
                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
       // Check if the clause is unrecognized.
-      if (CKind == OMPC_unknown)
+      if (CKind == OMPC_unknown) {
         Diag(Tok, diag::err_omp_expected_clause) << "metadirective";
+        TPA.Revert();
+        SkipUntil(tok::annot_pragma_openmp_end);
+        return Directive;
+      }
       if (getLangOpts().OpenMP < 52 && CKind == OMPC_otherwise)
         Diag(Tok, diag::err_omp_unexpected_clause)
             << getOpenMPClauseName(CKind) << "metadirective";
@@ -2678,8 +2682,11 @@ StmtResult 
Parser::ParseOpenMPDeclarativeOrExecutableDirective(
 
       // Parse '('.
       if (T.expectAndConsume(diag::err_expected_lparen_after,
-                             getOpenMPClauseName(CKind).data()))
+                             getOpenMPClauseName(CKind).data())) {
+        TPA.Revert();
+        SkipUntil(tok::annot_pragma_openmp_end);
         return Directive;
+      }
 
       OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
       if (CKind == OMPC_when) {

diff  --git a/clang/test/OpenMP/metadirective_messages.cpp 
b/clang/test/OpenMP/metadirective_messages.cpp
index a248e9a4e82a9..9d2934f8b1e10 100644
--- a/clang/test/OpenMP/metadirective_messages.cpp
+++ b/clang/test/OpenMP/metadirective_messages.cpp
@@ -49,3 +49,13 @@ void foo() {
       ;
   #endif
   }
+
+namespace GH139665 {
+void f(){
+#pragma omp metadirective( // expected-error {{expected at least one clause on 
'#pragma omp metadirective' directive}}
+}
+
+void g() {
+#pragma omp metadirective align // expected-error {{expected '(' after 
'align'}}
+}
+} // namespace GH139665


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to