[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