[clang] [OpenACC/OpenMP/Parser] Teach ParseCXXInlineMethods about pragmas (PR #214259)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 5 08:43:02 PDT 2026
https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/214259
Both OMP and OpenACC count on being able to reach their end-annotation token in order to properly recover from errors/leave the parser in good shape. This works well for 'free' functions.
However, when we do a pre-parse so we can delay-evaluate member functions, a stray end-brace can end up matching the end of the function. As a result, the examples in the test would have that brace ending with an EOF, which confused both of the pragma languages.
This patch teaches the ParseCXXInlineMethods functionality to ignore any braces/etc inside of a OpenACC/OpenMP pragma for the purposes of matching, since these shouldn't count towards that scoping anyway.
Fixes: #214195
>From 9f1714f3e5c8c37ead145cc99be7bf2a8058c2c1 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Wed, 5 Aug 2026 08:16:58 -0700
Subject: [PATCH] [OpenACC/OpenMP/Parser] Teach ParseCXXInlineMethods about
pragmas
Both OMP and OpenACC count on being able to reach their end-annotation
token in order to properly recover from errors/leave the parser in good
shape. This works well for 'free' functions.
However, when we do a pre-parse so we can delay-evaluate member
functions, a stray end-brace can end up matching the end of the
function. As a result, the examples in the test would have that brace
ending with an EOF, which confused both of the pragma languages.
This patch teaches the ParseCXXInlineMethods functionality to ignore any
braces/etc inside of a OpenACC/OpenMP pragma for the purposes of
matching, since these shouldn't count towards that scoping anyway.
Fixes: #214195
---
clang/lib/Parse/ParseCXXInlineMethods.cpp | 21 +++++++++++++++++++
clang/test/OpenMP/gh214195.cpp | 9 ++++++++
clang/test/ParserOpenACC/parse-constructs.cpp | 7 +++++++
3 files changed, 37 insertions(+)
create mode 100644 clang/test/OpenMP/gh214195.cpp
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index be531e567046e..3f101feb26a6d 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -870,6 +870,27 @@ bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
// Ran out of tokens.
return false;
+ case tok::annot_pragma_openacc:
+ case tok::annot_pragma_openmp:
+ case tok::annot_attr_openmp: {
+ // Ignore any tokens inside of a OMP/OpenACC pragma, as these should just
+ // be taken as 1.
+ tok::TokenKind EndKind = Tok.is(tok::annot_pragma_openacc)
+ ? tok::annot_pragma_openacc_end
+ : tok::annot_pragma_openmp_end;
+ Toks.push_back(Tok);
+ ConsumeAnnotationToken();
+ while (Tok.isNot(EndKind) && Tok.isNot(tok::eof)) {
+ Toks.push_back(Tok);
+ ConsumeAnyToken();
+ }
+ if (Tok.is(EndKind)) {
+ Toks.push_back(Tok);
+ ConsumeAnnotationToken();
+ }
+ break;
+ }
+
case tok::l_paren:
// Recursively consume properly-nested parens.
Toks.push_back(Tok);
diff --git a/clang/test/OpenMP/gh214195.cpp b/clang/test/OpenMP/gh214195.cpp
new file mode 100644
index 0000000000000..3247922412beb
--- /dev/null
+++ b/clang/test/OpenMP/gh214195.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -verify -fopenmp
+
+struct Type {
+ void foo() {
+#pragma omp parallel private(bar })
+ // expected-error at -1{{use of undeclared identifier 'bar'}}
+ // expected-error at +1{{expected statement}}
+ }
+};
diff --git a/clang/test/ParserOpenACC/parse-constructs.cpp b/clang/test/ParserOpenACC/parse-constructs.cpp
index 6d6285ce63bd2..abe3de899abc9 100644
--- a/clang/test/ParserOpenACC/parse-constructs.cpp
+++ b/clang/test/ParserOpenACC/parse-constructs.cpp
@@ -58,3 +58,10 @@ void foo() {
auto y = [](){};
#pragma acc routine (x) seq
}
+
+struct GH214195 {
+ void foo() {
+#pragma acc cache(bar })
+ // expected-error at -1{{use of undeclared identifier 'bar'}}
+ }
+};
More information about the cfe-commits
mailing list