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
