[clang] [clang][Sema] Preserve CV qualifiers when applying pointer and funcref attributes (PR #211709)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 24 05:25:41 PDT 2026


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/211709

>From b27235c563d816555c697acebeb06515df749b2b Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 23 Jul 2026 22:27:49 -0400
Subject: [PATCH 1/2] [Sema] Preserve CV qualifiers when applying pointer and
 funcref attributes

This patch fixes a bug in handleMSPointerTypeQualifierAttr and HandleWebAssemblyFuncrefAttr where applying these pointer attributes would implicitly drop top-level CV qualifiers (like `const`, `volatile`, and `restrict`) from the pointer type.
---
 clang/docs/ReleaseNotes.md               |  2 ++
 clang/lib/Sema/SemaType.cpp              | 10 ++++++++--
 clang/test/SemaCXX/ms-ptr-qualifiers.cpp | 19 +++++++++++++++++++
 clang/test/SemaCXX/wasm-funcref.cpp      |  3 +++
 4 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/SemaCXX/ms-ptr-qualifiers.cpp

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 83a2b10d96046..13647b6e316dc 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -355,6 +355,8 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to C++ Support
 
+- Fixed a bug where top-level CV qualifiers (such as ``const``) were dropped from pointers modified by Microsoft pointer attributes (like ``__ptr32`` and ``__ptr64``) and WebAssembly's ``__funcref``. This correctly restores the immutability of such pointers and prevents them from appearing identical to unqualified pointers in template instantiations and type traits.
+
 - Fixed an issue where we tried to compare invalid NTTPs for variable declarations, which ended up in hitting an assertion with a constrained non-plain-auto NTTP, which we don't quite implement yet. (#GH208658)
 
 - Fixed a crash when a using-declaration naming an unresolvable member of a
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1e9de3ef19f8e..427b1ca916bc9 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -7312,7 +7312,10 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
   if (ASIdx != LangAS::Default)
     Pointee = S.Context.getAddrSpaceQualType(
         S.Context.removeAddrSpaceQualType(Pointee), ASIdx);
-  Type = State.getAttributedType(A, Type, S.Context.getPointerType(Pointee));
+
+  QualType Equivalent = S.Context.getQualifiedType(
+      S.Context.getPointerType(Pointee), Type.getQualifiers());
+  Type = State.getAttributedType(A, Type, Equivalent);
   return false;
 }
 
@@ -7351,7 +7354,10 @@ static bool HandleWebAssemblyFuncrefAttr(TypeProcessingState &State,
   QualType Pointee = QT->getPointeeType();
   Pointee = S.Context.getAddrSpaceQualType(
       S.Context.removeAddrSpaceQualType(Pointee), ASIdx);
-  QT = State.getAttributedType(A, QT, S.Context.getPointerType(Pointee));
+
+  QualType Equivalent = S.Context.getQualifiedType(
+      S.Context.getPointerType(Pointee), QT.getQualifiers());
+  QT = State.getAttributedType(A, QT, Equivalent);
   return false;
 }
 
diff --git a/clang/test/SemaCXX/ms-ptr-qualifiers.cpp b/clang/test/SemaCXX/ms-ptr-qualifiers.cpp
new file mode 100644
index 0000000000000..48b208038befe
--- /dev/null
+++ b/clang/test/SemaCXX/ms-ptr-qualifiers.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -verify %s
+
+void test_const_qualifier() {
+  int A = 0;
+  int *const __ptr64 B = &A; // expected-note {{variable 'B' declared const here}}
+  B += 1; // expected-error {{cannot assign to variable 'B' with const-qualified type 'int *const __ptr64'}}
+
+  int *__ptr32 const C = &A; // expected-note {{variable 'C' declared const here}}
+  C = nullptr; // expected-error {{cannot assign to variable 'C' with const-qualified type 'int *const __ptr32'}}
+}
+
+void test_type_traits() {
+  static_assert(!__is_same(int *, int *const), "");
+  static_assert(!__is_same(int *__ptr32, int *__ptr32 const), "");
+  static_assert(!__is_same(int *__ptr64, int *__ptr64 const), "");
+  static_assert(!__is_same(int *__sptr __ptr32, int *__sptr __ptr32 const), "");
+  static_assert(!__is_same(int *__uptr __ptr32, int *__uptr __ptr32 const), "");
+  static_assert(!__is_same(int *__ptr32, int *__ptr32 volatile), "");
+}
diff --git a/clang/test/SemaCXX/wasm-funcref.cpp b/clang/test/SemaCXX/wasm-funcref.cpp
index 364565e9e803c..b6156a481e8e6 100644
--- a/clang/test/SemaCXX/wasm-funcref.cpp
+++ b/clang/test/SemaCXX/wasm-funcref.cpp
@@ -11,3 +11,6 @@ int get(int);
 IntIntFuncref getFuncref() {
     return get;
 }
+
+static_assert(!__is_same(IntIntFuncref, const IntIntFuncref), "");
+static_assert(!__is_same(int(*__funcref)(int), int(*const __funcref)(int)), "");

>From 519d87daf99d22717635c200e6b523b2ae28618b Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Fri, 24 Jul 2026 08:25:32 -0400
Subject: [PATCH 2/2] Revise and shorten release note text

---
 clang/docs/ReleaseNotes.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 13647b6e316dc..87d9a3b2433b3 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -355,7 +355,7 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to C++ Support
 
-- Fixed a bug where top-level CV qualifiers (such as ``const``) were dropped from pointers modified by Microsoft pointer attributes (like ``__ptr32`` and ``__ptr64``) and WebAssembly's ``__funcref``. This correctly restores the immutability of such pointers and prevents them from appearing identical to unqualified pointers in template instantiations and type traits.
+- Fixed a bug where top-level CV qualifiers (such as ``const``) were dropped from pointers modified by Microsoft pointer attributes (like ``__ptr32`` and ``__ptr64``) and WebAssembly's ``__funcref``.
 
 - Fixed an issue where we tried to compare invalid NTTPs for variable declarations, which ended up in hitting an assertion with a constrained non-plain-auto NTTP, which we don't quite implement yet. (#GH208658)
 



More information about the cfe-commits mailing list