https://github.com/jhuber6 updated 
https://github.com/llvm/llvm-project/pull/160185

>From be8d1e84e11274f64f931c6c52278e9d3d2daa82 Mon Sep 17 00:00:00 2001
From: Joseph Huber <[email protected]>
Date: Mon, 22 Sep 2025 14:26:40 -0500
Subject: [PATCH] [Clang][FIX] Fix type qualifiers on vector builtins

Summary:
These were not stripping qualifiers when using them to infer the types,
leading to errors when mixiing const and non-const.
---
 clang/lib/Sema/SemaChecking.cpp  | 61 +++++++++++++++++++++++++-------
 clang/test/Sema/builtin-masked.c | 26 ++++++++++++++
 2 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 27e3456bc6681..88725806a9920 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2296,12 +2296,21 @@ static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr 
*TheCall) {
   QualType PointeeTy = PtrTy->getPointeeType();
   const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
 
-  QualType RetTy =
-      S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
+  QualType RetTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),
+                                              MaskVecTy->getNumElements());
+  if (PtrTy->getPointeeType().isVolatileQualified())
+    return ExprError(
+        S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_convert_incompatible)
+        << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType()
+        << 5 /* different qualifiers */ << 0 /* qualifier difference */
+        << 3                                 /* parameter mismatch */
+        << 2 << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType());
   if (TheCall->getNumArgs() == 3) {
     Expr *PassThruArg = TheCall->getArg(2);
     QualType PassThruTy = PassThruArg->getType();
-    if (!S.Context.hasSameType(PassThruTy, RetTy))
+    if (!S.Context.hasSameType(PassThruTy, RetTy.getUnqualifiedType()))
       return S.Diag(PtrArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
              << /* third argument */ 3 << RetTy;
   }
@@ -2329,12 +2338,22 @@ static ExprResult BuiltinMaskedStore(Sema &S, CallExpr 
*TheCall) {
         S.Diag(ValArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
         << 2 << "vector");
 
+  if (PtrTy->getPointeeType().hasQualifiers())
+    return ExprError(
+        S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_convert_incompatible)
+        << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType()
+        << 5 /* different qualifiers */ << 0 /* qualifier difference */
+        << 3                                 /* parameter mismatch */
+        << 2 << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType());
+
   QualType PointeeTy = PtrTy->getPointeeType();
   const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
-  QualType RetTy =
-      S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
+  QualType RetTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),
+                                              MaskVecTy->getNumElements());
 
-  if (!S.Context.hasSameType(ValTy, RetTy))
+  if (!S.Context.hasSameType(ValTy.getUnqualifiedType(), RetTy))
     return ExprError(S.Diag(TheCall->getBeginLoc(),
                             diag::err_vec_builtin_incompatible_vector)
                      << TheCall->getDirectCallee() << /*isMorethantwoArgs*/ 2
@@ -2366,6 +2385,15 @@ static ExprResult BuiltinMaskedGather(Sema &S, CallExpr 
*TheCall) {
   QualType PtrTy = PtrArg->getType();
   QualType PointeeTy = PtrTy->getPointeeType();
   const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
+  if (PtrTy->getPointeeType().isVolatileQualified())
+    return ExprError(
+        S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_convert_incompatible)
+        << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType()
+        << 5 /* different qualifiers */ << 0 /* qualifier difference */
+        << 3                                 /* parameter mismatch */
+        << 2 << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType());
   if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())
     return ExprError(
         S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
@@ -2373,12 +2401,12 @@ static ExprResult BuiltinMaskedGather(Sema &S, CallExpr 
*TheCall) {
                TheCall->getBuiltinCallee())
         << MaskTy << IdxTy);
 
-  QualType RetTy =
-      S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
+  QualType RetTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),
+                                              MaskVecTy->getNumElements());
   if (TheCall->getNumArgs() == 4) {
     Expr *PassThruArg = TheCall->getArg(3);
     QualType PassThruTy = PassThruArg->getType();
-    if (!S.Context.hasSameType(PassThruTy, RetTy))
+    if (!S.Context.hasSameType(PassThruTy.getUnqualifiedType(), RetTy))
       return S.Diag(PassThruArg->getExprLoc(),
                     diag::err_vec_masked_load_store_ptr)
              << /* fourth argument */ 4 << RetTy;
@@ -2414,6 +2442,15 @@ static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr 
*TheCall) {
 
   const VectorType *MaskVecTy = MaskTy->castAs<VectorType>();
   const VectorType *ValVecTy = ValTy->castAs<VectorType>();
+  if (PtrTy->getPointeeType().hasQualifiers())
+    return ExprError(
+        S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_convert_incompatible)
+        << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType()
+        << 5 /* different qualifiers */ << 0 /* qualifier difference */
+        << 3                                 /* parameter mismatch */
+        << 2 << PtrTy->getPointeeType()
+        << PtrTy->getPointeeType().getUnqualifiedType());
   if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())
     return ExprError(
         S.Diag(TheCall->getBeginLoc(), diag::err_vec_masked_load_store_size)
@@ -2427,9 +2464,9 @@ static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr 
*TheCall) {
                TheCall->getBuiltinCallee())
         << MaskTy << ValTy);
 
-  QualType ArgTy =
-      S.Context.getExtVectorType(PointeeTy, MaskVecTy->getNumElements());
-  if (!S.Context.hasSameType(ValTy, ArgTy))
+  QualType ArgTy = S.Context.getExtVectorType(PointeeTy.getUnqualifiedType(),
+                                              MaskVecTy->getNumElements());
+  if (!S.Context.hasSameType(ValTy.getUnqualifiedType(), ArgTy))
     return ExprError(S.Diag(TheCall->getBeginLoc(),
                             diag::err_vec_builtin_incompatible_vector)
                      << TheCall->getDirectCallee() << /*isMoreThanTwoArgs*/ 2
diff --git a/clang/test/Sema/builtin-masked.c b/clang/test/Sema/builtin-masked.c
index e24648da57fb1..c010bfab2ec60 100644
--- a/clang/test/Sema/builtin-masked.c
+++ b/clang/test/Sema/builtin-masked.c
@@ -54,3 +54,29 @@ void test_masked_scatter(int *p, v8i idx, v8b mask, v2b 
mask2, v8i val) {
   __builtin_masked_scatter(mask, idx, val, idx); // expected-error {{3rd 
argument must be a scalar pointer}}
   __builtin_masked_scatter(mask, idx, val, &idx); // expected-error {{3rd 
argument must be a scalar pointer}}
 }
+
+void a(v8b mask, v8i val, const int *ptr) {
+  __builtin_masked_load(mask, ptr, val);
+  (void)__builtin_masked_load(mask, (volatile int *)ptr, val); // 
expected-error {{sending 'volatile int' to parameter of incompatible type 
'int': type mismatch at 2nd parameter ('volatile int' vs 'int')}}
+}
+
+void b(v8b mask, v8i idx, const int *ptr) {
+  (void)__builtin_masked_gather(mask, idx, ptr);
+  (void)__builtin_masked_gather(mask, idx, (volatile int *)ptr); // 
expected-error {{sending 'volatile int' to parameter of incompatible type 
'int': type mismatch at 2nd parameter ('volatile int' vs 'int')}}
+}
+
+void c(v8b mask, const v8i val, int *ptr) {
+  __builtin_masked_store(mask, val, ptr);
+}
+
+void readonly(v8b mask, v8i val, const int *ptr, const int *s) {
+  __builtin_masked_store(mask, val, ptr); // expected-error {{sending 'const 
int' to parameter of incompatible type 'int': type mismatch at 2nd parameter 
('const int' vs 'int')}}
+  __builtin_masked_compress_store(mask, val, ptr); // expected-error {{sending 
'const int' to parameter of incompatible type 'int': type mismatch at 2nd 
parameter ('const int' vs 'int')}}
+  __builtin_masked_scatter(mask, val, val, s); // expected-error {{sending 
'const int' to parameter of incompatible type 'int': type mismatch at 2nd 
parameter ('const int' vs 'int')}}
+}
+
+void vol(v8b mask, v8i val, volatile int *ptr, volatile int *s) {
+  __builtin_masked_store(mask, val, ptr); // expected-error {{sending 
'volatile int' to parameter of incompatible type 'int': type mismatch at 2nd 
parameter ('volatile int' vs 'int')}}
+  __builtin_masked_compress_store(mask, val, ptr); // expected-error {{sending 
'volatile int' to parameter of incompatible type 'int': type mismatch at 2nd 
parameter ('volatile int' vs 'int')}}
+  __builtin_masked_scatter(mask, val, val, s); // expected-error {{sending 
'volatile int' to parameter of incompatible type 'int': type mismatch at 2nd 
parameter ('volatile int' vs 'int')}}
+}

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

Reply via email to