-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[clang] Restrict the use of scalar types in vector builtins #119423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
3f007d7
4d39f93
479f384
ad8ccba
80a8399
453460f
f009991
9d7e79d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14594,11 +14594,18 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) { | |
| _2, _3, _4)); | ||
| } | ||
|
|
||
| static ExprResult UsualUnaryConversionsNoPromoteInt(Sema &S, Expr *E) { | ||
| // Don't promote integer types | ||
| if (QualType Ty = E->getType(); S.getASTContext().isPromotableIntegerType(Ty)) | ||
| return S.DefaultFunctionArrayLvalueConversion(E); | ||
| return S.UsualUnaryConversions(E); | ||
|
||
| } | ||
|
|
||
| bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) { | ||
| if (checkArgCount(TheCall, 1)) | ||
| return true; | ||
|
|
||
| ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); | ||
| ExprResult A = UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(0)); | ||
| if (A.isInvalid()) | ||
| return true; | ||
|
|
||
|
|
@@ -14613,57 +14620,63 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) { | |
| } | ||
|
|
||
| bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) { | ||
| QualType Res; | ||
| if (BuiltinVectorMath(TheCall, Res, FPOnly)) | ||
| return true; | ||
| TheCall->setType(Res); | ||
| return false; | ||
| if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) { | ||
| TheCall->setType(*Res); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) { | ||
| QualType Res; | ||
| if (BuiltinVectorMath(TheCall, Res)) | ||
| std::optional<QualType> Res = BuiltinVectorMath(TheCall); | ||
| if (!Res) | ||
| return true; | ||
|
|
||
| if (auto *VecTy0 = Res->getAs<VectorType>()) | ||
| if (auto *VecTy0 = (*Res)->getAs<VectorType>()) | ||
| TheCall->setType(VecTy0->getElementType()); | ||
| else | ||
| TheCall->setType(Res); | ||
| TheCall->setType(*Res); | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) { | ||
| std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall, | ||
| bool FPOnly) { | ||
| if (checkArgCount(TheCall, 2)) | ||
| return true; | ||
| return std::nullopt; | ||
|
|
||
| ExprResult A = TheCall->getArg(0); | ||
| ExprResult B = TheCall->getArg(1); | ||
| // Do standard promotions between the two arguments, returning their common | ||
| // type. | ||
| Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison); | ||
| if (A.isInvalid() || B.isInvalid()) | ||
| return true; | ||
| checkEnumArithmeticConversions(TheCall->getArg(0), TheCall->getArg(1), | ||
| TheCall->getExprLoc(), ACK_Comparison); | ||
|
||
|
|
||
| QualType TyA = A.get()->getType(); | ||
| QualType TyB = B.get()->getType(); | ||
| Expr *Args[2]; | ||
| for (int I = 0; I < 2; ++I) { | ||
| ExprResult Converted = | ||
| UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I)); | ||
| if (Converted.isInvalid()) | ||
| return std::nullopt; | ||
| Args[I] = Converted.get(); | ||
| } | ||
|
|
||
| if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType()) | ||
| return Diag(A.get()->getBeginLoc(), | ||
| diag::err_typecheck_call_different_arg_types) | ||
| << TyA << TyB; | ||
| SourceLocation LocA = Args[0]->getBeginLoc(); | ||
| QualType TyA = Args[0]->getType(); | ||
| QualType TyB = Args[1]->getType(); | ||
|
|
||
| if (TyA.getCanonicalType() != TyB.getCanonicalType()) { | ||
| Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB; | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| if (FPOnly) { | ||
| if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1)) | ||
| return true; | ||
| if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1)) | ||
| return std::nullopt; | ||
| } else { | ||
| if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1)) | ||
| return true; | ||
| if (checkMathBuiltinElementType(*this, LocA, TyA, 1)) | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| TheCall->setArg(0, A.get()); | ||
| TheCall->setArg(1, B.get()); | ||
| return false; | ||
| TheCall->setArg(0, Args[0]); | ||
| TheCall->setArg(1, Args[1]); | ||
| return TyA; | ||
| } | ||
|
|
||
| bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, | ||
|
|
@@ -14673,7 +14686,8 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, | |
|
|
||
| Expr *Args[3]; | ||
| for (int I = 0; I < 3; ++I) { | ||
| ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I)); | ||
| ExprResult Converted = | ||
| UsualUnaryConversionsNoPromoteInt(*this, TheCall->getArg(I)); | ||
| if (Converted.isInvalid()) | ||
| return true; | ||
| Args[I] = Converted.get(); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.