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@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(L"") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(L"bar") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-warning@+1 {{WARNING}} +#pragma omp error severity(warning) message(L"bar") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(1) +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+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@+2 {{expected string literal in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(msg) +// expected-warning@+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@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(L"") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(L"msg") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(u"msg") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-error@+1 {{ERROR}} +#pragma omp error message(U"msg") +// expected-warning@+2 {{expected string in 'clause message' - ignoring}} +// expected-warning@+1 {{WARNING}} +#pragma omp error severity(warning) message(L"msg") +#ifdef __cpp_char8_t +// expected-warning@+5 {{expected string in 'clause message' - ignoring}} +// expected-error@+4 {{ERROR}} +#else +// expected-error@+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@+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") _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
