llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Akash Manna (akash-manna-sky) <details> <summary>Changes</summary> Fixes #<!-- -->140338 The `message` clause accepted any character-typed string, checked with `isAnyCharacterType()`, but everything that consumes it assumes a narrow string: Sema evaluates it into a `std::string` for the compile-time diagnostic, and codegen passes it straight to `__kmpc_error`'s `char *` parameter. 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` and `char8_t` element types. Wide and UTF-16/32 literals get the existing "expected string in 'clause message' - ignoring" warning and the directive still fires with its generic message, which is what C already did and what GCC does with `<message unknown at compile time>`. Doing this at the single point where the clause is built covers the diagnostic, both codegen paths, and template instantiation without touching the evaluator. --- Full diff: https://github.com/llvm/llvm-project/pull/226080.diff 5 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+1) - (modified) clang/lib/Sema/SemaOpenMP.cpp (+7-2) - (added) clang/test/OpenMP/error_message.c (+33) - (modified) clang/test/OpenMP/error_message.cpp (+21) - (modified) clang/test/OpenMP/parallel_message_messages.cpp (+1-1) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index f4a34a37aff52..48222a212c8af 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -529,6 +529,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 wide or UTF-16/32 string literal. Such literals are now diagnosed and ignored, as they already were in C. (#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 2e4d9f2f82f0b..c9aa5a8b50227 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -18369,8 +18369,13 @@ OMPClause *SemaOpenMP::ActOnOpenMPMessageClause(Expr *ME, SourceLocation EndLoc) { assert(ME && "NULL expr in Message clause"); QualType Type = ME->getType(); - if ((!Type->isPointerType() && !Type->isArrayType()) || - !Type->getPointeeOrArrayElementType()->isAnyCharacterType()) { + // The message is consumed as a narrow string by Sema and the runtime. + bool IsNarrowString = false; + if (Type->isPointerType() || Type->isArrayType()) { + const auto *ElemTy = Type->getPointeeOrArrayElementType(); + IsNarrowString = ElemTy->isCharType() || ElemTy->isChar8Type(); + } + if (!IsNarrowString) { 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..d07c4d8b75c58 100644 --- a/clang/test/OpenMP/error_message.cpp +++ b/clang/test/OpenMP/error_message.cpp @@ -7,6 +7,24 @@ // 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") +#pragma omp error message(u8"msg") // expected-error {{msg}} + template <class T> T tmain(T argc) { if (argc) @@ -202,5 +220,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") `````````` </details> https://github.com/llvm/llvm-project/pull/226080 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
