@@ -1698,18 +1698,27 @@ static bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
16981698 return true ;
16991699}
17001700
1701- static bool CheckArgsTypesAreCorrect (
1701+ bool CheckArgTypeIsCorrect (
1702+ Sema *S, Expr *Arg, QualType ExpectedType,
1703+ llvm::function_ref<bool (clang::QualType PassedType)> Check) {
1704+ QualType PassedType = Arg->getType ();
1705+ if (Check (PassedType)) {
1706+ if (auto *VecTyA = PassedType->getAs <VectorType>())
1707+ ExpectedType = S->Context .getVectorType (
1708+ ExpectedType, VecTyA->getNumElements (), VecTyA->getVectorKind ());
1709+ S->Diag (Arg->getBeginLoc (), diag::err_typecheck_convert_incompatible)
1710+ << PassedType << ExpectedType << 1 << 0 << 0 ;
1711+ return true ;
1712+ }
1713+ return false ;
1714+ }
1715+
1716+ bool CheckAllArgTypesAreCorrect (
17021717 Sema *S, CallExpr *TheCall, QualType ExpectedType,
17031718 llvm::function_ref<bool (clang::QualType PassedType)> Check) {
17041719 for (unsigned i = 0 ; i < TheCall->getNumArgs (); ++i) {
1705- QualType PassedType = TheCall->getArg (i)->getType ();
1706- if (Check (PassedType)) {
1707- if (auto *VecTyA = PassedType->getAs <VectorType>())
1708- ExpectedType = S->Context .getVectorType (
1709- ExpectedType, VecTyA->getNumElements (), VecTyA->getVectorKind ());
1710- S->Diag (TheCall->getArg (0 )->getBeginLoc (),
1711- diag::err_typecheck_convert_incompatible)
1712- << PassedType << ExpectedType << 1 << 0 << 0 ;
1720+ Expr *Arg = TheCall->getArg (i);
1721+ if (CheckArgTypeIsCorrect (S, Arg, ExpectedType, Check)) {
17131722 return true ;
17141723 }
17151724 }
@@ -1720,8 +1729,8 @@ static bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) {
17201729 auto checkAllFloatTypes = [](clang::QualType PassedType) -> bool {
17211730 return !PassedType->hasFloatingRepresentation ();
17221731 };
1723- return CheckArgsTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1724- checkAllFloatTypes);
1732+ return CheckAllArgTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1733+ checkAllFloatTypes);
17251734}
17261735
17271736static bool CheckFloatOrHalfRepresentations (Sema *S, CallExpr *TheCall) {
@@ -1732,8 +1741,19 @@ static bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) {
17321741 : PassedType;
17331742 return !BaseType->isHalfType () && !BaseType->isFloat32Type ();
17341743 };
1735- return CheckArgsTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1736- checkFloatorHalf);
1744+ return CheckAllArgTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1745+ checkFloatorHalf);
1746+ }
1747+
1748+ static bool CheckModifiableLValue (Sema *S, CallExpr *TheCall,
1749+ unsigned ArgIndex) {
1750+ auto *Arg = TheCall->getArg (ArgIndex);
1751+ SourceLocation OrigLoc = Arg->getExprLoc ();
1752+ if (Arg->IgnoreCasts ()->isModifiableLvalue (S->Context , &OrigLoc) ==
1753+ Expr::MLV_Valid)
1754+ return false ;
1755+ S->Diag (OrigLoc, diag::error_hlsl_inout_lvalue) << Arg << 0 ;
1756+ return true ;
17371757}
17381758
17391759static bool CheckNoDoubleVectors (Sema *S, CallExpr *TheCall) {
@@ -1742,24 +1762,24 @@ static bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) {
17421762 return VecTy->getElementType ()->isDoubleType ();
17431763 return false ;
17441764 };
1745- return CheckArgsTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1746- checkDoubleVector);
1765+ return CheckAllArgTypesAreCorrect (S, TheCall, S->Context .FloatTy ,
1766+ checkDoubleVector);
17471767}
17481768static bool CheckFloatingOrIntRepresentation (Sema *S, CallExpr *TheCall) {
17491769 auto checkAllSignedTypes = [](clang::QualType PassedType) -> bool {
17501770 return !PassedType->hasIntegerRepresentation () &&
17511771 !PassedType->hasFloatingRepresentation ();
17521772 };
1753- return CheckArgsTypesAreCorrect (S, TheCall, S->Context .IntTy ,
1754- checkAllSignedTypes);
1773+ return CheckAllArgTypesAreCorrect (S, TheCall, S->Context .IntTy ,
1774+ checkAllSignedTypes);
17551775}
17561776
17571777static bool CheckUnsignedIntRepresentation (Sema *S, CallExpr *TheCall) {
17581778 auto checkAllUnsignedTypes = [](clang::QualType PassedType) -> bool {
17591779 return !PassedType->hasUnsignedIntegerRepresentation ();
17601780 };
1761- return CheckArgsTypesAreCorrect (S, TheCall, S->Context .UnsignedIntTy ,
1762- checkAllUnsignedTypes);
1781+ return CheckAllArgTypesAreCorrect (S, TheCall, S->Context .UnsignedIntTy ,
1782+ checkAllUnsignedTypes);
17631783}
17641784
17651785static void SetElementTypeAsReturnType (Sema *S, CallExpr *TheCall,
@@ -2074,6 +2094,22 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
20742094 return true ;
20752095 break ;
20762096 }
2097+ case Builtin::BI__builtin_hlsl_elementwise_splitdouble: {
2098+ if (SemaRef.checkArgCount (TheCall, 3 ))
2099+ return true ;
2100+
2101+ if (CheckScalarOrVector (&SemaRef, TheCall, SemaRef.Context .DoubleTy , 0 ) ||
2102+ CheckScalarOrVector (&SemaRef, TheCall, SemaRef.Context .UnsignedIntTy ,
2103+ 1 ) ||
2104+ CheckScalarOrVector (&SemaRef, TheCall, SemaRef.Context .UnsignedIntTy ,
2105+ 2 ))
2106+ return true ;
2107+
2108+ if (CheckModifiableLValue (&SemaRef, TheCall, 1 ) ||
2109+ CheckModifiableLValue (&SemaRef, TheCall, 2 ))
2110+ return true ;
2111+ break ;
2112+ }
20772113 case Builtin::BI__builtin_elementwise_acos:
20782114 case Builtin::BI__builtin_elementwise_asin:
20792115 case Builtin::BI__builtin_elementwise_atan:
0 commit comments