[clang] [Clang] Reject __annotation on unsupported targets (PR #193731)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 28 03:03:30 PDT 2026
https://github.com/kjedruczyk updated https://github.com/llvm/llvm-project/pull/193731
>From 9f4a8007ac96ee96e15da962e0bc51c9429c5761 Mon Sep 17 00:00:00 2001
From: Krzysztof Jedruczyk <kjedruczyk at bloomberg.net>
Date: Thu, 23 Apr 2026 13:22:02 +0100
Subject: [PATCH 1/5] [Clang] Fix char width assumption in __annotation
---
clang/lib/CodeGen/CGBuiltin.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 7a745b6e36138..67de2a34f44ea 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5597,12 +5597,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
SmallVector<Metadata *, 1> Strings;
for (const Expr *Arg : E->arguments()) {
const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
- assert(Str->getCharByteWidth() == 2);
+ assert(Str->getCharByteWidth() == 2 || Str->getCharByteWidth() == 4);
StringRef WideBytes = Str->getBytes();
std::string StrUtf8;
- if (!convertUTF16ToUTF8String(
- ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
- CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
+ bool Converted =
+ (Str->getCharByteWidth() == 2)
+ ? convertUTF16ToUTF8String(
+ ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)
+ : convertUTF32ToUTF8String(
+ ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8);
+ if (!Converted) {
+ CGM.ErrorUnsupported(E, "non-Unicode __annotation argument");
continue;
}
Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
>From 544d08cb0f4ed96cbe4bc1cad65134a8950b767d Mon Sep 17 00:00:00 2001
From: Krzysztof Jedruczyk <kjedruczyk at bloomberg.net>
Date: Fri, 24 Apr 2026 14:39:04 +0100
Subject: [PATCH 2/5] [Clang] Reject __annotation on unsupported targets
__annotation emits llvm.codeview.annotation intrinsics, which are only
consumed by CodeViewDebug on Windows and UEFI targets.
---
clang/lib/CodeGen/CGBuiltin.cpp | 13 ++++---------
clang/lib/Sema/SemaChecking.cpp | 9 ++++++++-
clang/test/Sema/ms-annotation.c | 19 ++++++++++++-------
3 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 67de2a34f44ea..7a745b6e36138 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5597,17 +5597,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
SmallVector<Metadata *, 1> Strings;
for (const Expr *Arg : E->arguments()) {
const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
- assert(Str->getCharByteWidth() == 2 || Str->getCharByteWidth() == 4);
+ assert(Str->getCharByteWidth() == 2);
StringRef WideBytes = Str->getBytes();
std::string StrUtf8;
- bool Converted =
- (Str->getCharByteWidth() == 2)
- ? convertUTF16ToUTF8String(
- ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)
- : convertUTF32ToUTF8String(
- ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8);
- if (!Converted) {
- CGM.ErrorUnsupported(E, "non-Unicode __annotation argument");
+ if (!convertUTF16ToUTF8String(
+ ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
+ CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
continue;
}
Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7caae4e66f5b7..1113ae26c422b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3263,10 +3263,17 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI##ID: \
return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
#include "clang/Basic/Builtins.inc"
- case Builtin::BI__annotation:
+ case Builtin::BI__annotation: {
+ const llvm::Triple &TT = Context.getTargetInfo().getTriple();
+ if (!TT.isOSWindows() && !TT.isUEFI()) {
+ Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
+ << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
+ return ExprError();
+ }
if (BuiltinMSVCAnnotation(*this, TheCall))
return ExprError();
break;
+ }
case Builtin::BI__builtin_annotation:
if (BuiltinAnnotation(*this, TheCall))
return ExprError();
diff --git a/clang/test/Sema/ms-annotation.c b/clang/test/Sema/ms-annotation.c
index 9a2beebf065a2..ea9844bcfbeca 100644
--- a/clang/test/Sema/ms-annotation.c
+++ b/clang/test/Sema/ms-annotation.c
@@ -1,13 +1,18 @@
// RUN: %clang_cc1 -triple i686-windows %s -verify -fms-extensions
// RUN: %clang_cc1 -x c++ -std=c++11 -triple i686-windows %s -verify -fms-extensions
// RUN: %clang_cc1 -x c++ -std=c++14 -triple i686-windows %s -verify -fms-extensions
+// RUN: %clang_cc1 -triple x86_64-unknown-uefi %s -verify -fms-extensions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -verify=unsupported -fms-extensions
void test1(void) {
- __annotation(); // expected-error {{too few arguments to function call, expected at least 1, have 0}}
- __annotation(1); // expected-error {{must be wide string constants}}
- __annotation(L"a1");
- __annotation(L"a1", L"a2");
- __annotation(L"a1", L"a2", 42); // expected-error {{must be wide string constants}}
- __annotation(L"a1", L"a2", L"a3");
- __annotation(L"multi " L"part " L"string");
+ __annotation(); // expected-error {{too few arguments to function call, expected at least 1, have 0}} \
+ // unsupported-error {{builtin is not supported on this target}}
+ __annotation(1); // expected-error {{must be wide string constants}} \
+ // unsupported-error {{builtin is not supported on this target}}
+ __annotation(L"a1"); // unsupported-error {{builtin is not supported on this target}}
+ __annotation(L"a1", L"a2"); // unsupported-error {{builtin is not supported on this target}}
+ __annotation(L"a1", L"a2", 42); // expected-error {{must be wide string constants}} \
+ // unsupported-error {{builtin is not supported on this target}}
+ __annotation(L"a1", L"a2", L"a3"); // unsupported-error {{builtin is not supported on this target}}
+ __annotation(L"multi " L"part " L"string"); // unsupported-error {{builtin is not supported on this target}}
}
>From 4942bc5cd1f4d4530f0a36ec69cd66c248bc7197 Mon Sep 17 00:00:00 2001
From: Krzysztof Jedruczyk <kjedruczyk at bloomberg.net>
Date: Fri, 24 Apr 2026 18:20:30 +0100
Subject: [PATCH 3/5] [Clang] Add release note for __annotation target
restriction
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8d60450f54669..7a249f088b97c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -500,6 +500,8 @@ Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Fix a crash when passing an unresolved overload set to ``__builtin_classify_type``. (#GH175589)
- Fixed a crash when calling `__builtin_allow_sanitize_check` with no arguments. (#GH183927)
+- ``__annotation`` is now diagnosed as unsupported on non-Windows/UEFI targets, fixing a
+ crash when using it with ``-fms-extensions`` on other platforms. (#GH184318)
Bug Fixes to Attribute Support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>From 22389be389f85f295ea204d2ecd6d37a0439a8d8 Mon Sep 17 00:00:00 2001
From: kjedruczyk <krzysztof.jedruczyk at gmail.com>
Date: Fri, 24 Apr 2026 18:52:11 +0100
Subject: [PATCH 4/5] Apply suggestions from code review
Co-authored-by: Corentin Jabot <corentinjabot at gmail.com>
---
clang/lib/Sema/SemaChecking.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 1113ae26c422b..eb957df6f1e97 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3267,7 +3267,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
const llvm::Triple &TT = Context.getTargetInfo().getTriple();
if (!TT.isOSWindows() && !TT.isUEFI()) {
Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported)
- << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc());
+ << TheCall->getSourceRange();
return ExprError();
}
if (BuiltinMSVCAnnotation(*this, TheCall))
>From 4482b45072a4936d08e9fd71edbc24f013d24b6d Mon Sep 17 00:00:00 2001
From: Krzysztof Jedruczyk <kjedruczyk at bloomberg.net>
Date: Tue, 28 Apr 2026 10:02:53 +0100
Subject: [PATCH 5/5] [Clang] Fix char width assumption in __annotation
Since `-fno-short-wchar` is technically allowed on Windows and UEFI targets,
make sure the UTF8 conversion of __annotation literal works with these settings.
---
clang/lib/CodeGen/CGBuiltin.cpp | 13 +++++++++----
clang/test/CodeGen/ms-annotation.c | 1 +
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 7a745b6e36138..67de2a34f44ea 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5597,12 +5597,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
SmallVector<Metadata *, 1> Strings;
for (const Expr *Arg : E->arguments()) {
const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
- assert(Str->getCharByteWidth() == 2);
+ assert(Str->getCharByteWidth() == 2 || Str->getCharByteWidth() == 4);
StringRef WideBytes = Str->getBytes();
std::string StrUtf8;
- if (!convertUTF16ToUTF8String(
- ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
- CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
+ bool Converted =
+ (Str->getCharByteWidth() == 2)
+ ? convertUTF16ToUTF8String(
+ ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)
+ : convertUTF32ToUTF8String(
+ ArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8);
+ if (!Converted) {
+ CGM.ErrorUnsupported(E, "non-Unicode __annotation argument");
continue;
}
Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
diff --git a/clang/test/CodeGen/ms-annotation.c b/clang/test/CodeGen/ms-annotation.c
index 8ad48366bfdae..19d36c625b231 100644
--- a/clang/test/CodeGen/ms-annotation.c
+++ b/clang/test/CodeGen/ms-annotation.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows %s -fms-extensions -fwchar-type=int -fsigned-wchar -emit-llvm -o - | FileCheck %s
//
// Test that LLVM optimizations leave these intrinsics alone, for the most part.
// RUN: %clang_cc1 -O2 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
More information about the cfe-commits
mailing list