https://github.com/trungnt2910 updated 
https://github.com/llvm/llvm-project/pull/185282

>From 825d065ef2d32e3374104b7b607abade434701a9 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Mon, 9 Mar 2026 01:28:03 +1100
Subject: [PATCH 1/8] [clang] Add support for `[[msvc::forceinline]]`

This is equivalent to Microsoft's `__forceinline` when placed before
a function declaration.
Unlike `__forceinline`, `[[msvc::forceinline]]` works with lambdas.

This is implemented as an alias of `[[clang::always_inline]]`.
---
 clang/include/clang/Basic/Attr.td          |  3 ++-
 clang/test/CodeGen/attr-ms-forceinline.cpp | 16 ++++++++++++++++
 clang/test/Sema/attr-ms-forceinline.cpp    |  9 +++++++++
 3 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/attr-ms-forceinline.cpp
 create mode 100644 clang/test/Sema/attr-ms-forceinline.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index befd671393c7c..446a5abc250e8 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -927,7 +927,8 @@ def AlignNatural : InheritableAttr {
 
 def AlwaysInline : DeclOrStmtAttr {
   let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
-                   C23<"clang", "always_inline">, 
CustomKeyword<"__forceinline">];
+                   C23<"clang", "always_inline">, 
CustomKeyword<"__forceinline">,
+                   CXX11<"msvc", "forceinline">, C23<"msvc", "forceinline">];
   let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", 
"always_inline">,
                                                     C23<"clang", 
"always_inline">]>];
   let Subjects = SubjectList<[Function, Stmt], WarnDiag,
diff --git a/clang/test/CodeGen/attr-ms-forceinline.cpp 
b/clang/test/CodeGen/attr-ms-forceinline.cpp
new file mode 100644
index 0000000000000..240e58b8a8e52
--- /dev/null
+++ b/clang/test/CodeGen/attr-ms-forceinline.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc -o 
- | FileCheck %s
+
+[[msvc::forceinline]] void func() {}
+
+void call_func() {
+// CHECK-LABEL: @"?call_func@@YAXXZ"()
+// CHECK-NOT: call void @"?func@@YAXXZ"()
+  func();
+}
+
+void call_lambda() {
+// CHECK-LABEL: @"?call_lambda@@YAXXZ"()
+// CHECK-NOT: call void @"??R<lambda_
+  auto lambda = [] [[msvc::forceinline]] () {};
+  lambda();
+}
diff --git a/clang/test/Sema/attr-ms-forceinline.cpp 
b/clang/test/Sema/attr-ms-forceinline.cpp
new file mode 100644
index 0000000000000..6e5ac191ce8d1
--- /dev/null
+++ b/clang/test/Sema/attr-ms-forceinline.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++23 -triple x86_64-windows %s
+// expected-no-diagnostics
+
+[[msvc::forceinline]] void func(void) {}
+
+void lambda() {
+  auto l = [] [[msvc::forceinline]] () {};
+  l();
+}

>From 72a2f22ab2e02aaf034539343ca7d6a4ad458fd8 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Wed, 18 Mar 2026 07:21:16 +1100
Subject: [PATCH 2/8] [clang] Try removing triple from test

---
 clang/test/Sema/attr-ms-forceinline.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Sema/attr-ms-forceinline.cpp 
b/clang/test/Sema/attr-ms-forceinline.cpp
index 6e5ac191ce8d1..619c7c8fb62da 100644
--- a/clang/test/Sema/attr-ms-forceinline.cpp
+++ b/clang/test/Sema/attr-ms-forceinline.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++23 -triple x86_64-windows %s
+// RUN: %clang_cc1 -verify -fsyntax-only -std=c++23 %s
 // expected-no-diagnostics
 
 [[msvc::forceinline]] void func(void) {}

>From b1d3deed72d24a44e8a864fd913499eee586334f Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Fri, 27 Mar 2026 23:31:42 +1100
Subject: [PATCH 3/8] Test [[msvc::forceinline]] with non-MSVC triple

This ensures that the feature is not artificially restricted to the MSVC 
compatibility mode.
---
 clang/test/CodeGen/attr-ms-forceinline.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/clang/test/CodeGen/attr-ms-forceinline.cpp 
b/clang/test/CodeGen/attr-ms-forceinline.cpp
index 240e58b8a8e52..580fea044a803 100644
--- a/clang/test/CodeGen/attr-ms-forceinline.cpp
+++ b/clang/test/CodeGen/attr-ms-forceinline.cpp
@@ -1,16 +1,21 @@
-// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc -o 
- | FileCheck %s
+// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc -o 
- | FileCheck -check-prefix=CHECK-MSVC %s
+// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-unknown-linux-gnu 
-o - | FileCheck -check-prefix=CHECK-LINUX %s
 
 [[msvc::forceinline]] void func() {}
 
 void call_func() {
-// CHECK-LABEL: @"?call_func@@YAXXZ"()
-// CHECK-NOT: call void @"?func@@YAXXZ"()
+// CHECK-MSVC-LABEL: @"?call_func@@YAXXZ"()
+// CHECK-MSVC-NOT: call void @"?func@@YAXXZ"()
+// CHECK-LINUX-LABEL: @_Z9call_funcv()
+// CHECK-LINUX-NOT: call void @_Z4funcv()
   func();
 }
 
 void call_lambda() {
-// CHECK-LABEL: @"?call_lambda@@YAXXZ"()
-// CHECK-NOT: call void @"??R<lambda_
+// CHECK-MSVC-LABEL: @"?call_lambda@@YAXXZ"()
+// CHECK-MSVC-NOT: call void @"??R<lambda_
+// CHECK-LINUX-LABEL: @_Z11call_lambdav()
+// CHECK-LINUX-NOT: call void @"_ZZ11call_lambdavENK3$_0clEv"
   auto lambda = [] [[msvc::forceinline]] () {};
   lambda();
 }

>From b4e09722a11c9b6c53dff529f38611cebf131fd0 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Tue, 31 Mar 2026 23:30:48 +1100
Subject: [PATCH 4/8] [clang] Address review feedback

- Add tests for C23 and later attributes. They are identical to the C++
tests except for the lambda.
- Added sema tests for:
  + Applying `[[msvc::forceinline]]` to a statement.
  + Applying `[[msvc::forceinline_calls]]` to a function.
  + Passing unwanted arguments to the attributes.
  + Using the attributes without enabling MS extensions (they are
  ignored).
- Add support for `[[msvc::forceinline_calls]]`.
- Guard the two attributes with `-fms-extensions`.
---
 clang/include/clang/Basic/Attr.td             |  9 ++++-
 .../clang/Basic/DiagnosticSemaKinds.td        |  5 +++
 clang/lib/Sema/SemaDeclAttr.cpp               | 12 ++++++
 clang/lib/Sema/SemaStmtAttr.cpp               | 12 +++++-
 clang/test/CodeGen/attr-ms-forceinline.cpp    | 31 +++++++++++-----
 clang/test/Sema/attr-ms-forceinline.c         | 32 ++++++++++++++++
 clang/test/Sema/attr-ms-forceinline.cpp       | 37 +++++++++++++++++--
 7 files changed, 122 insertions(+), 16 deletions(-)
 create mode 100644 clang/test/Sema/attr-ms-forceinline.c

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 446a5abc250e8..6a1c91c58ff29 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -928,9 +928,14 @@ def AlignNatural : InheritableAttr {
 def AlwaysInline : DeclOrStmtAttr {
   let Spellings = [GCC<"always_inline">, CXX11<"clang", "always_inline">,
                    C23<"clang", "always_inline">, 
CustomKeyword<"__forceinline">,
-                   CXX11<"msvc", "forceinline">, C23<"msvc", "forceinline">];
+                   CXX11<"msvc", "forceinline">, C23<"msvc", "forceinline">,
+                   CXX11<"msvc", "forceinline_calls">, C23<"msvc", 
"forceinline_calls">];
   let Accessors = [Accessor<"isClangAlwaysInline", [CXX11<"clang", 
"always_inline">,
-                                                    C23<"clang", 
"always_inline">]>];
+                                                    C23<"clang", 
"always_inline">]>,
+                   Accessor<"isMSVCForceInline", [CXX11<"msvc", "forceinline">,
+                                                  C23<"msvc", "forceinline">]>,
+                   Accessor<"isMSVCForceInlineCalls", [CXX11<"msvc", 
"forceinline_calls">,
+                                                       C23<"msvc", 
"forceinline_calls">]>];
   let Subjects = SubjectList<[Function, Stmt], WarnDiag,
                              "functions and statements">;
   let Documentation = [AlwaysInlineDocs];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0e6b3f51a5231..ebf3245221dbc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3269,6 +3269,11 @@ def warn_function_attribute_ignored_in_stmt : Warning<
   "use '%0' on statements">,
   InGroup<IgnoredAttributes>;
 
+def warn_stmt_attribute_ignored_in_function : Warning<
+  "attribute is ignored on this function as it only applies to statements; "
+  "use '%0' for functions">,
+  InGroup<IgnoredAttributes>;
+
 def err_musttail_needs_trivial_args : Error<
   "tail call requires that the return value, all parameters, and any "
   "temporaries created by the expression are trivially destructible">;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1b7f41061061d..94ff47790a1d4 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5130,6 +5130,18 @@ OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
 }
 
 static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  AlwaysInlineAttr AIA(S.Context, AL);
+  if (!S.getLangOpts().MicrosoftExt &&
+      (AIA.isMSVCForceInline() || AIA.isMSVCForceInlineCalls())) {
+    S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
+    return;
+  }
+  if (AIA.isMSVCForceInlineCalls()) {
+    S.Diag(AL.getLoc(), diag::warn_stmt_attribute_ignored_in_function)
+        << "[[msvc::forceinline]]";
+    return;
+  }
+
   if (AlwaysInlineAttr *Inline =
           S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
     D->addAttr(Inline);
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index 27fd5563cc40e..f45c4333f94f6 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -312,7 +312,17 @@ static Attr *handleNoInlineAttr(Sema &S, Stmt *St, const 
ParsedAttr &A,
 static Attr *handleAlwaysInlineAttr(Sema &S, Stmt *St, const ParsedAttr &A,
                                     SourceRange Range) {
   AlwaysInlineAttr AIA(S.Context, A);
-  if (!AIA.isClangAlwaysInline()) {
+  if (!S.getLangOpts().MicrosoftExt &&
+      (AIA.isMSVCForceInline() || AIA.isMSVCForceInlineCalls())) {
+    S.Diag(St->getBeginLoc(), diag::warn_attribute_ignored) << A;
+    return nullptr;
+  }
+  if (AIA.isMSVCForceInline()) {
+    S.Diag(St->getBeginLoc(), diag::warn_function_attribute_ignored_in_stmt)
+        << "[[msvc::forceinline_calls]]";
+    return nullptr;
+  }
+  if (!AIA.isClangAlwaysInline() && !AIA.isMSVCForceInlineCalls()) {
     S.Diag(St->getBeginLoc(), diag::warn_function_attribute_ignored_in_stmt)
         << "[[clang::always_inline]]";
     return nullptr;
diff --git a/clang/test/CodeGen/attr-ms-forceinline.cpp 
b/clang/test/CodeGen/attr-ms-forceinline.cpp
index 580fea044a803..dd9e00f536e20 100644
--- a/clang/test/CodeGen/attr-ms-forceinline.cpp
+++ b/clang/test/CodeGen/attr-ms-forceinline.cpp
@@ -1,14 +1,16 @@
-// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc -o 
- | FileCheck -check-prefix=CHECK-MSVC %s
-// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-unknown-linux-gnu 
-o - | FileCheck -check-prefix=CHECK-LINUX %s
+// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc 
-fms-extensions -o - | FileCheck -check-prefix=CHECK-MSVC %s
+// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-unknown-linux-gnu 
-fms-extensions -o - | FileCheck -check-prefix=CHECK-LINUX %s
 
-[[msvc::forceinline]] void func() {}
+[[msvc::forceinline]] void foo() {}
 
-void call_func() {
-// CHECK-MSVC-LABEL: @"?call_func@@YAXXZ"()
-// CHECK-MSVC-NOT: call void @"?func@@YAXXZ"()
-// CHECK-LINUX-LABEL: @_Z9call_funcv()
-// CHECK-LINUX-NOT: call void @_Z4funcv()
-  func();
+void bar() {}
+
+void call_foo() {
+// CHECK-MSVC-LABEL: @"?call_foo@@YAXXZ"()
+// CHECK-MSVC-NOT: call void @"?foo@@YAXXZ"()
+// CHECK-LINUX-LABEL: @_Z8call_foov()
+// CHECK-LINUX-NOT: call void @_Z3foov()
+  foo();
 }
 
 void call_lambda() {
@@ -19,3 +21,14 @@ void call_lambda() {
   auto lambda = [] [[msvc::forceinline]] () {};
   lambda();
 }
+
+void call_bar_stmt() {
+// CHECK-MSVC-LABEL: @"?call_bar_stmt@@YAXXZ"()
+// CHECK-MSVC: call void @"?bar@@YAXXZ"() #[[ALWAYSINLINEATTR:[0-9]+]]
+// CHECK-LINUX-LABEL: @_Z13call_bar_stmtv()
+// CHECK-LINUX: call void @_Z3barv() #[[ALWAYSINLINEATTR:[0-9]+]]
+  [[msvc::forceinline_calls]] bar();
+}
+
+// CHECK-MSVC: attributes #[[ALWAYSINLINEATTR]] = { alwaysinline }
+// CHECK-LINUX: attributes #[[ALWAYSINLINEATTR]] = { alwaysinline }
diff --git a/clang/test/Sema/attr-ms-forceinline.c 
b/clang/test/Sema/attr-ms-forceinline.c
new file mode 100644
index 0000000000000..bda31ea3eff97
--- /dev/null
+++ b/clang/test/Sema/attr-ms-forceinline.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify=ms-ext -fms-extensions -fsyntax-only -std=c23 %s
+// RUN: %clang_cc1 -verify=no-ms-ext -fsyntax-only -std=c23 %s
+
+void foo(void);
+
+[[msvc::forceinline]] void func(void) {}
+// no-ms-ext-warning@-1 {{'msvc::forceinline' attribute ignored}}
+
+void stmt_forceinline(void) {
+  [[msvc::forceinline]] func();
+  // ms-ext-warning@-1 {{attribute is ignored on this statement as it only 
applies to functions; use '[[msvc::forceinline_calls]]' on statements}}
+  // no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+}
+
+[[msvc::forceinline_calls]] void func2(void) {}
+// ms-ext-warning@-1 {{attribute is ignored on this function as it only 
applies to statements; use '[[msvc::forceinline]]' for functions}}
+// no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+
+void stmt_forceinline_calls(void) {
+  [[msvc::forceinline_calls]] foo();
+  // no-ms-ext-warning@-1 {{'msvc::forceinline_calls' attribute ignored}}
+}
+
+[[msvc::forceinline(0)]] void func3(void);
+// ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
+// no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+
+void func4(void) {
+    [[msvc::forceinline_calls("foo")]] foo();
+    // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
+    // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+}
diff --git a/clang/test/Sema/attr-ms-forceinline.cpp 
b/clang/test/Sema/attr-ms-forceinline.cpp
index 619c7c8fb62da..5292470514a9e 100644
--- a/clang/test/Sema/attr-ms-forceinline.cpp
+++ b/clang/test/Sema/attr-ms-forceinline.cpp
@@ -1,9 +1,38 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -std=c++23 %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -verify=ms-ext -fms-extensions -fsyntax-only -std=c++23 %s
+// RUN: %clang_cc1 -verify=no-ms-ext -fsyntax-only -std=c++23 %s
 
-[[msvc::forceinline]] void func(void) {}
+void foo();
 
-void lambda() {
+[[msvc::forceinline]] void func() {}
+// no-ms-ext-warning@-1 {{'msvc::forceinline' attribute ignored}}
+
+void lambda_func() {
   auto l = [] [[msvc::forceinline]] () {};
+  // no-ms-ext-warning@-1 {{'msvc::forceinline' attribute ignored}}
   l();
 }
+
+void stmt_forceinline() {
+  [[msvc::forceinline]] func();
+  // ms-ext-warning@-1 {{attribute is ignored on this statement as it only 
applies to functions; use '[[msvc::forceinline_calls]]' on statements}}
+  // no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+}
+
+[[msvc::forceinline_calls]] void func2() {}
+// ms-ext-warning@-1 {{attribute is ignored on this function as it only 
applies to statements; use '[[msvc::forceinline]]' for functions}}
+// no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+
+void stmt_forceinline_calls() {
+  [[msvc::forceinline_calls]] foo();
+  // no-ms-ext-warning@-1 {{'msvc::forceinline_calls' attribute ignored}}
+}
+
+[[msvc::forceinline(0)]] void func3();
+// ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
+// no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+
+void func4() {
+    [[msvc::forceinline_calls("foo")]] foo();
+    // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
+    // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+}

>From 0ab171d706ee963093d9276fd69b53a9902f0006 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Wed, 1 Apr 2026 00:09:53 +1100
Subject: [PATCH 5/8] [clang] Fix test failures

---
 clang/test/CodeGen/attr-ms-forceinline.cpp | 2 +-
 clang/test/Sema/attr-ms-forceinline.c      | 6 +++---
 clang/test/Sema/attr-ms-forceinline.cpp    | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang/test/CodeGen/attr-ms-forceinline.cpp 
b/clang/test/CodeGen/attr-ms-forceinline.cpp
index dd9e00f536e20..a44f5d05b29af 100644
--- a/clang/test/CodeGen/attr-ms-forceinline.cpp
+++ b/clang/test/CodeGen/attr-ms-forceinline.cpp
@@ -3,7 +3,7 @@
 
 [[msvc::forceinline]] void foo() {}
 
-void bar() {}
+void bar();
 
 void call_foo() {
 // CHECK-MSVC-LABEL: @"?call_foo@@YAXXZ"()
diff --git a/clang/test/Sema/attr-ms-forceinline.c 
b/clang/test/Sema/attr-ms-forceinline.c
index bda31ea3eff97..d80cabdba67b8 100644
--- a/clang/test/Sema/attr-ms-forceinline.c
+++ b/clang/test/Sema/attr-ms-forceinline.c
@@ -26,7 +26,7 @@ void stmt_forceinline_calls(void) {
 // no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
 
 void func4(void) {
-    [[msvc::forceinline_calls("foo")]] foo();
-    // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
-    // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+  [[msvc::forceinline_calls("foo")]] foo();
+  // ms-ext-error@-1 {{'msvc::forceinline_calls' attribute takes no arguments}}
+  // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
 }
diff --git a/clang/test/Sema/attr-ms-forceinline.cpp 
b/clang/test/Sema/attr-ms-forceinline.cpp
index 5292470514a9e..72b165b25c021 100644
--- a/clang/test/Sema/attr-ms-forceinline.cpp
+++ b/clang/test/Sema/attr-ms-forceinline.cpp
@@ -32,7 +32,7 @@ void stmt_forceinline_calls() {
 // no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
 
 void func4() {
-    [[msvc::forceinline_calls("foo")]] foo();
-    // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
-    // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+  [[msvc::forceinline_calls("foo")]] foo();
+  // ms-ext-error@-1 {{'msvc::forceinline_calls' attribute takes no arguments}}
+  // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
 }

>From 42593afba9436b6ef48d8ca6f2e842f9541261e2 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Wed, 1 Apr 2026 00:32:28 +1100
Subject: [PATCH 6/8] [clang] Fix last test errors

---
 clang/test/Sema/attr-ms-forceinline.c   | 4 ++--
 clang/test/Sema/attr-ms-forceinline.cpp | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/Sema/attr-ms-forceinline.c 
b/clang/test/Sema/attr-ms-forceinline.c
index d80cabdba67b8..1da92e89f2178 100644
--- a/clang/test/Sema/attr-ms-forceinline.c
+++ b/clang/test/Sema/attr-ms-forceinline.c
@@ -23,10 +23,10 @@ void stmt_forceinline_calls(void) {
 
 [[msvc::forceinline(0)]] void func3(void);
 // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
-// no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+// no-ms-ext-error@-2 {{'msvc::forceinline' attribute takes no arguments}}
 
 void func4(void) {
   [[msvc::forceinline_calls("foo")]] foo();
   // ms-ext-error@-1 {{'msvc::forceinline_calls' attribute takes no arguments}}
-  // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+  // no-ms-ext-error@-2 {{'msvc::forceinline_calls' attribute takes no 
arguments}}
 }
diff --git a/clang/test/Sema/attr-ms-forceinline.cpp 
b/clang/test/Sema/attr-ms-forceinline.cpp
index 72b165b25c021..5e1d2b3eeee85 100644
--- a/clang/test/Sema/attr-ms-forceinline.cpp
+++ b/clang/test/Sema/attr-ms-forceinline.cpp
@@ -29,10 +29,10 @@ void stmt_forceinline_calls() {
 
 [[msvc::forceinline(0)]] void func3();
 // ms-ext-error@-1 {{'msvc::forceinline' attribute takes no arguments}}
-// no-ms-ext-warning@-2 {{'msvc::forceinline' attribute ignored}}
+// no-ms-ext-error@-2 {{'msvc::forceinline' attribute takes no arguments}}
 
 void func4() {
   [[msvc::forceinline_calls("foo")]] foo();
   // ms-ext-error@-1 {{'msvc::forceinline_calls' attribute takes no arguments}}
-  // no-ms-ext-warning@-2 {{'msvc::forceinline_calls' attribute ignored}}
+  // no-ms-ext-error@-2 {{'msvc::forceinline_calls' attribute takes no 
arguments}}
 }

>From fd131e6980cfdb7a00e8bb9fec719b7146b779bd Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Wed, 1 Apr 2026 00:55:41 +1100
Subject: [PATCH 7/8] [clang] Document attributes in release notes

---
 clang/docs/ReleaseNotes.rst | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5d07bfc210e05..f3885b636a21c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -207,6 +207,10 @@ Attribute Changes in Clang
   type-level control over overflow behavior. There is also an accompanying type
   specifier for each behavior kind via `__ob_wrap` and `__ob_trap`.
 
+- Added support for ``[[msvc::forceinline]]`` for functions and 
``[[msvc::forceinline_calls]]`` for
+  statements. Both are aliases to ``[clang::always_inlines]`` with additional 
checks to ensure that
+  they are only accepted in places where MSVC also does.
+
 Improvements to Clang's diagnostics
 -----------------------------------
 - Added ``-Wlifetime-safety`` to enable lifetime safety analysis,
@@ -273,13 +277,13 @@ Improvements to Clang's diagnostics
   when accessing a member function on a past-the-end array element.
   (#GH179128)
 
-- Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and 
+- Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and
   made sure that only one such diagnostic and FixIt is emitted per declaration 
group. (#GH179354)
 
 - The ``-Wloop-analysis`` warning has been extended to catch more cases of
   variable modification inside lambda expressions (#GH132038).
 
-- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use 
the sizeof 
+- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use 
the sizeof
   the destination buffer(dynamically allocated) in the len parameter(#GH162366)
 
 - ``-Wunsafe-buffer-usage`` now warns about unsafe two-parameter constructors 
of
@@ -337,12 +341,12 @@ Bug Fixes to C++ Support
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
 - Fixed a crash when pack expansions are used as arguments for non-pack 
parameters of built-in templates. (#GH180307)
-- Fixed a bug where captured variables in non-mutable lambdas were incorrectly 
treated as mutable 
+- Fixed a bug where captured variables in non-mutable lambdas were incorrectly 
treated as mutable
   when used inside decltype in the return type. (#GH180460)
 - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type 
vectors in ``constexpr``. (#GH180044)
 - Fixed a crash on ``typeid`` of incomplete local types during template 
instantiation. (#GH63242), (#GH176397)
-- Inherited constructors in ``dllexport`` classes are now exported for 
ABI-compatible cases, matching 
-  MSVC behavior. Constructors with variadic arguments or callee-cleanup 
parameters are not yet supported 
+- Inherited constructors in ``dllexport`` classes are now exported for 
ABI-compatible cases, matching
+  MSVC behavior. Constructors with variadic arguments or callee-cleanup 
parameters are not yet supported
   and produce a warning. (#GH162640)
 
 - Fix initialization of GRO when GRO-return type mismatches, as part of 
CWG2563. (#GH98744)

>From bb639a4491fc267cfce2d8fd988608904f039e83 Mon Sep 17 00:00:00 2001
From: Trung Nguyen <[email protected]>
Date: Wed, 1 Apr 2026 01:28:30 +1100
Subject: [PATCH 8/8] [clang] Test for attributes instead

---
 clang/test/CodeGen/attr-ms-forceinline.cpp | 42 +++++++++++-----------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/clang/test/CodeGen/attr-ms-forceinline.cpp 
b/clang/test/CodeGen/attr-ms-forceinline.cpp
index a44f5d05b29af..aca13f54b4e77 100644
--- a/clang/test/CodeGen/attr-ms-forceinline.cpp
+++ b/clang/test/CodeGen/attr-ms-forceinline.cpp
@@ -1,34 +1,32 @@
-// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-pc-windows-msvc 
-fms-extensions -o - | FileCheck -check-prefix=CHECK-MSVC %s
-// RUN: %clang_cc1 -std=c++23 -emit-llvm %s -triple x86_64-unknown-linux-gnu 
-fms-extensions -o - | FileCheck -check-prefix=CHECK-LINUX %s
+// RUN: %clang_cc1 -std=c++23 -disable-llvm-passes -emit-llvm %s -triple 
x86_64-pc-windows-msvc -fms-extensions -o - | FileCheck 
-check-prefix=CHECK-MSVC %s
+// RUN: %clang_cc1 -std=c++23 -disable-llvm-passes -emit-llvm %s -triple 
x86_64-unknown-linux-gnu -fms-extensions -o - | FileCheck 
-check-prefix=CHECK-LINUX %s
 
+// CHECK-MSVC: define {{.*}} @"?foo@@YAXXZ"() #[[ATTR_FOO:[0-9]+]]
+// CHECK-LINUX: define {{.*}} @_Z3foov() #[[ATTR_FOO:[0-9]+]]
 [[msvc::forceinline]] void foo() {}
 
 void bar();
 
-void call_foo() {
-// CHECK-MSVC-LABEL: @"?call_foo@@YAXXZ"()
-// CHECK-MSVC-NOT: call void @"?foo@@YAXXZ"()
-// CHECK-LINUX-LABEL: @_Z8call_foov()
-// CHECK-LINUX-NOT: call void @_Z3foov()
-  foo();
-}
-
 void call_lambda() {
-// CHECK-MSVC-LABEL: @"?call_lambda@@YAXXZ"()
-// CHECK-MSVC-NOT: call void @"??R<lambda_
-// CHECK-LINUX-LABEL: @_Z11call_lambdav()
-// CHECK-LINUX-NOT: call void @"_ZZ11call_lambdavENK3$_0clEv"
-  auto lambda = [] [[msvc::forceinline]] () {};
+  auto lambda = [] [[msvc::forceinline]] () { bar(); };
   lambda();
 }
 
-void call_bar_stmt() {
-// CHECK-MSVC-LABEL: @"?call_bar_stmt@@YAXXZ"()
-// CHECK-MSVC: call void @"?bar@@YAXXZ"() #[[ALWAYSINLINEATTR:[0-9]+]]
-// CHECK-LINUX-LABEL: @_Z13call_bar_stmtv()
-// CHECK-LINUX: call void @_Z3barv() #[[ALWAYSINLINEATTR:[0-9]+]]
+// CHECK-MSVC: define internal void 
@"??R<lambda_0>@?0??call_lambda@@YAXXZ@QEBA?A?<auto>@@XZ"{{.*}} 
#[[ATTR_LAMBDA:[0-9]+]]
+// CHECK-LINUX: define internal void @"_ZZ11call_lambdavENK3$_0clEv"{{.*}} 
#[[ATTR_LAMBDA:[0-9]+]]
+
+void call_bar() {
+// CHECK-MSVC-LABEL: define {{.*}} @"?call_bar@@YAXXZ"()
+// CHECK-MSVC: call void @"?bar@@YAXXZ"() #[[ATTR_CALLSITE:[0-9]+]]
+// CHECK-LINUX-LABEL: define {{.*}} @_Z8call_barv()
+// CHECK-LINUX: call void @_Z3barv() #[[ATTR_CALLSITE:[0-9]+]]
   [[msvc::forceinline_calls]] bar();
 }
 
-// CHECK-MSVC: attributes #[[ALWAYSINLINEATTR]] = { alwaysinline }
-// CHECK-LINUX: attributes #[[ALWAYSINLINEATTR]] = { alwaysinline }
+// CHECK-MSVC: attributes #[[ATTR_FOO]] = { alwaysinline {{.*}} }
+// CHECK-MSVC: attributes #[[ATTR_LAMBDA]] = { alwaysinline {{.*}} }
+// CHECK-MSVC: attributes #[[ATTR_CALLSITE]] = { alwaysinline }
+
+// CHECK-LINUX: attributes #[[ATTR_FOO]] = { alwaysinline {{.*}} }
+// CHECK-LINUX: attributes #[[ATTR_LAMBDA]] = { alwaysinline {{.*}} }
+// CHECK-LINUX: attributes #[[ATTR_CALLSITE]] = { alwaysinline }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to