[clang] [Clang][FIX] Fix type qualifiers on vector builtins (PR #160185)
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 22 13:58:23 PDT 2025
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/160185
>From 7b4ba2fff8e810adddf1cbdb1d9945600b53b940 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 22 Sep 2025 14:26:40 -0500
Subject: [PATCH 1/2] [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 | 20 +++++++++++---------
clang/test/Sema/builtin-masked.c | 12 ++++++++++++
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 740b472b0eb16..7ffc3c3395f5f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2302,7 +2302,8 @@ static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall) {
if (TheCall->getNumArgs() == 3) {
Expr *PassThruArg = TheCall->getArg(2);
QualType PassThruTy = PassThruArg->getType();
- if (!S.Context.hasSameType(PassThruTy, PointeeTy))
+ if (!S.Context.hasSameType(PassThruTy.getUnqualifiedType(),
+ PointeeTy.getUnqualifiedType()))
return S.Diag(PtrArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
<< /* third argument */ 3 << PointeeTy;
}
@@ -2314,7 +2315,7 @@ static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall) {
TheCall->getBuiltinCallee())
<< MaskTy << PointeeTy);
- TheCall->setType(PointeeTy);
+ TheCall->setType(PointeeTy.getUnqualifiedType());
return TheCall;
}
@@ -2350,7 +2351,8 @@ static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall) {
TheCall->getBuiltinCallee())
<< MaskTy << PointeeTy);
- if (!S.Context.hasSameType(ValTy, PointeeTy))
+ if (!S.Context.hasSameType(ValTy.getUnqualifiedType(),
+ PointeeTy.getUnqualifiedType()))
return ExprError(S.Diag(TheCall->getBeginLoc(),
diag::err_vec_builtin_incompatible_vector)
<< TheCall->getDirectCallee() << /*isMorethantwoArgs*/ 2
@@ -2389,12 +2391,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;
@@ -2443,9 +2445,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 eb0070b0276af..020b0a5250de4 100644
--- a/clang/test/Sema/builtin-masked.c
+++ b/clang/test/Sema/builtin-masked.c
@@ -64,3 +64,15 @@ 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}}
}
+
+v8i a(v8b mask, v8i val, const v8i *ptr) {
+ return __builtin_masked_load(mask, ptr, val);
+}
+
+v8i b(v8b mask, v8i idx, const int *ptr) {
+ return __builtin_masked_gather(mask, idx, ptr);
+}
+
+void c(v8b mask, const v8i val, v8i *ptr) {
+ __builtin_masked_store(mask, val, ptr);
+}
>From 999aefb4540104c432a87a898545277f365317f0 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 22 Sep 2025 15:58:13 -0500
Subject: [PATCH 2/2] Const fix
---
clang/lib/Sema/SemaChecking.cpp | 10 ++++++++++
clang/test/Sema/builtin-masked.c | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7ffc3c3395f5f..f6f5599b3298f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2338,6 +2338,11 @@ static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall) {
S.Diag(ValArg->getExprLoc(), diag::err_vec_masked_load_store_ptr)
<< 2 << "vector");
+ if (PtrTy->getPointeeType().isConstQualified())
+ return ExprError(
+ S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_assign_const)
+ << /*read-only*/ 5);
+
QualType PointeeTy = PtrTy->getPointeeType();
const VectorType *MaskVecTy = MaskTy->getAs<VectorType>();
const VectorType *ValVecTy = ValTy->getAs<VectorType>();
@@ -2430,6 +2435,11 @@ static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall) {
QualType PtrTy = PtrArg->getType();
QualType PointeeTy = PtrTy->getPointeeType();
+ if (PtrTy->getPointeeType().isConstQualified())
+ return ExprError(
+ S.Diag(PtrArg->getExprLoc(), diag::err_typecheck_assign_const)
+ << /*read-only*/ 5);
+
const VectorType *MaskVecTy = MaskTy->castAs<VectorType>();
const VectorType *ValVecTy = ValTy->castAs<VectorType>();
if (MaskVecTy->getNumElements() != IdxVecTy->getNumElements())
diff --git a/clang/test/Sema/builtin-masked.c b/clang/test/Sema/builtin-masked.c
index 020b0a5250de4..651dc508060ec 100644
--- a/clang/test/Sema/builtin-masked.c
+++ b/clang/test/Sema/builtin-masked.c
@@ -76,3 +76,9 @@ v8i b(v8b mask, v8i idx, const int *ptr) {
void c(v8b mask, const v8i val, v8i *ptr) {
__builtin_masked_store(mask, val, ptr);
}
+
+void readonly(v8b mask, v8i val, const v8i *ptr, const int *s) {
+ __builtin_masked_store(mask, val, ptr); // expected-error {{read-only variable is not assignable}}
+ __builtin_masked_compress_store(mask, val, ptr); // expected-error {{read-only variable is not assignable}}
+ __builtin_masked_scatter(mask, val, val, s); // expected-error {{read-only variable is not assignable}}
+}
More information about the cfe-commits
mailing list