[clang] 5eb23d2 - [clang][OpenMP] Only accept char strings in the message clause (#226080)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 24 07:34:02 PDT 2026
Author: Akash Manna
Date: 2026-09-24T10:33:54-04:00
New Revision: 5eb23d2ae9f1dab06a31e5f9d7d64fa23a775604
URL: https://github.com/llvm/llvm-project/commit/5eb23d2ae9f1dab06a31e5f9d7d64fa23a775604
DIFF: https://github.com/llvm/llvm-project/commit/5eb23d2ae9f1dab06a31e5f9d7d64fa23a775604.diff
LOG: [clang][OpenMP] Only accept char strings in the message clause (#226080)
Fixes #140338
The `message` clause accepted any character-typed string, checked with
`isAnyCharacterType()`, but everything that consumes it assumes a `char`
string: Sema evaluates it into a `std::string` for the compile-time
diagnostic, and codegen passes it straight to the `const char *`
parameter of `__kmpc_error` and `__kmpc_push_num_threads_strict`. When
the issue was filed this hit the assertion in
`StringLiteral::getString()`. Since #146405 the assert is gone, but the
underlying problem stayed: in C++ a wide literal like `message(L"bar")`
prints `b<NUL><NUL>` as the error text, and with `at(execution)` a
`wchar_t` array is emitted as the runtime's `char *` argument. C was
only spared because `wchar_t` is an integer typedef there, so the clause
was already rejected.
The clause now only accepts `char` element types, which is what the spec
requires (OpenMP 5.1 ยง2.5.4: msg-string is a string of `const char *`
type). Wide, `UTF-16/32` and C++20 `u8` literals get the existing
"expected string in 'clause message' - ignoring" warning and the
directive still fires with its generic message, matching what C already
did and what GCC does. Doing this at the single point where the clause
is built covers the diagnostic, both codegen paths, and template
instantiation without touching the evaluator.
Added:
clang/test/OpenMP/error_message.c
Modified:
clang/docs/ReleaseNotes.md
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/error_message.cpp
clang/test/OpenMP/parallel_message_messages.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 4349f342b3b89..69206eb21ab2e 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -533,6 +533,7 @@ features cannot lower the translation-unit ABI level;
- Fixed a constraint comparison bug in partial ordering. (#GH182671)
- Fixed a rejected-valid case that used an explicit object parameter in an out-of-line definition of a nested class member. (#GH136472)
- Fixed an assertion on omp taskloop transparent (#GH197162)
+- Fixed an assertion failure and a garbled diagnostic when the `message` clause of `#pragma omp error` was given a string literal that is not of `char` type, such as a wide string literal. Such literals are now diagnosed and ignored. (#GH140338)
- Fixed a bug where `__func__`, `__PRETTY_FUNCTION__` and `__FUNCTION__` were not resolving to the proper function when inside a lambda return type (#GH211811)
- Fixed USR generation for declarations whose signature mentions a class-type
non-type template parameter. (#GH212351)
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 3ea7348271ea5..654968d4a5749 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -19239,8 +19239,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPMessageClause(Expr *ME,
SourceLocation EndLoc) {
assert(ME && "NULL expr in Message clause");
QualType Type = ME->getType();
+ // OpenMP 5.1 [2.5.4, error Directive]
+ // msg-string is a string of const char * type.
if ((!Type->isPointerType() && !Type->isArrayType()) ||
- !Type->getPointeeOrArrayElementType()->isAnyCharacterType()) {
+ !Type->getPointeeOrArrayElementType()->isCharType()) {
Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
<< getOpenMPClauseNameForDiag(OMPC_message) << 0;
return nullptr;
diff --git a/clang/test/OpenMP/error_message.c b/clang/test/OpenMP/error_message.c
new file mode 100644
index 0000000000000..82c533d54b631
--- /dev/null
+++ b/clang/test/OpenMP/error_message.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ferror-limit 100 %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 %s
+
+// GH140338
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(L"")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(L"bar")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-warning at +1 {{WARNING}}
+#pragma omp error severity(warning) message(L"bar")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(1)
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(1.2)
+#pragma omp error message("foo") // expected-error {{foo}}
+#pragma omp error message(u8"foo") // expected-error {{foo}}
+
+int foo(int i, const char *msg) {
+// expected-warning at +2 {{expected string literal in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(msg)
+// expected-warning at +1 {{expected string in 'clause message' - ignoring}}
+#pragma omp error at(execution) message(L"bar") // no error
+ return i;
+}
diff --git a/clang/test/OpenMP/error_message.cpp b/clang/test/OpenMP/error_message.cpp
index e96562eaa023f..fb615e50c2244 100644
--- a/clang/test/OpenMP/error_message.cpp
+++ b/clang/test/OpenMP/error_message.cpp
@@ -4,9 +4,35 @@
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify -std=c++20 -fopenmp -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized
+
// Test outside of an executable context.
#pragma omp error severity(warning) message("msg") at(compilation) // expected-warning {{msg}}
+// GH140338
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(L"")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(L"msg")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(u"msg")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-error at +1 {{ERROR}}
+#pragma omp error message(U"msg")
+// expected-warning at +2 {{expected string in 'clause message' - ignoring}}
+// expected-warning at +1 {{WARNING}}
+#pragma omp error severity(warning) message(L"msg")
+#ifdef __cpp_char8_t
+// expected-warning at +5 {{expected string in 'clause message' - ignoring}}
+// expected-error at +4 {{ERROR}}
+#else
+// expected-error at +2 {{msg}}
+#endif
+#pragma omp error message(u8"msg")
+
template <class T>
T tmain(T argc) {
if (argc)
@@ -202,5 +228,8 @@ if (1)
label2:
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
+// expected-warning at +1 {{expected string in 'clause message' - ignoring}}
+#pragma omp error at(execution) message(L"msg") // no error
+
return tmain(argc);// expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}}
}
diff --git a/clang/test/OpenMP/parallel_message_messages.cpp b/clang/test/OpenMP/parallel_message_messages.cpp
index ea8fa23ef5e53..1ec9a37a1b7fa 100644
--- a/clang/test/OpenMP/parallel_message_messages.cpp
+++ b/clang/test/OpenMP/parallel_message_messages.cpp
@@ -62,7 +62,7 @@ T tmain(T argc, S **argv) {
#pragma omp parallel message("hello" " world")
// Message clause with wide string literal
- #pragma omp parallel message(L"wide string")
+ #pragma omp parallel message(L"wide string") // expected-warning {{expected string in 'clause message' - ignoring}}
// Message clause with UTF-8 string literal
#pragma omp parallel message(u8"utf8 string")
More information about the cfe-commits
mailing list