diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 75b99e7d09..e3c002c1f8 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -2539,7 +2539,7 @@ SpirvInstruction *SpirvEmitter::getBaseOfMemberFunction( SpirvInstruction *SpirvEmitter::processCall(const CallExpr *callExpr) { const FunctionDecl *callee = getCalleeDefinition(callExpr); - // Note that we always want the defintion because Stmts/Exprs in the + // Note that we always want the definition because Stmts/Exprs in the // function body references the parameters in the definition. if (!callee) { emitError("found undefined function", callExpr->getExprLoc()); @@ -2641,7 +2641,7 @@ SpirvInstruction *SpirvEmitter::processCall(const CallExpr *callExpr) { const uint32_t argIndex = i + isOperatorOverloading; // We want the argument variable here so that we can write back to it - // later. We will do the OpLoad of this argument manually. So ingore + // later. We will do the OpLoad of this argument manually. So ignore // the LValueToRValue implicit cast here. auto *arg = callExpr->getArg(argIndex)->IgnoreParenLValueCasts(); const auto *param = callee->getParamDecl(i); @@ -7771,6 +7771,16 @@ SpirvInstruction *SpirvEmitter::castToFloat(SpirvInstruction *fromVal, } if (isFloatOrVecOfFloatType(fromType)) { + uint32_t fromCount = 0; + const bool fromIsVec = isVectorType(fromType, nullptr, &fromCount); + uint32_t toCount = 0; + const bool toIsVec = isVectorType(toFloatType, nullptr, &toCount); + + if (fromIsVec != toIsVec || fromCount != toCount) { + emitError("casting from %0 to %1 unsupported", srcLoc) << fromType << + toFloatType; + return nullptr; + } // This is the case of float to float conversion with different bitwidths. return convertBitwidth(fromVal, srcLoc, fromType, toFloatType, nullptr, range); diff --git a/tools/clang/test/CodeGenSPIRV/cast.scalar-to-vec.implicit.hlsl b/tools/clang/test/CodeGenSPIRV/cast.scalar-to-vec.implicit.hlsl new file mode 100644 index 0000000000..406de72b7d --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/cast.scalar-to-vec.implicit.hlsl @@ -0,0 +1,18 @@ +// RUN: %dxc -T cs_6_0 -E main + +RWTexture2D g_output; + +void foo(inout float3 x) +{ + x += float3(1, 2, 3); +} + +// CHECK: error: casting from 'float' to 'float3' unsupported + +[numthreads(1, 1, 1)] +void main(uint3 id : SV_DispatchThreadId) +{ + float bar = 1; + foo(bar); + g_output[id.xy] = bar; +} diff --git a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp index fed2885dae..660acaf33d 100644 --- a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp +++ b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp @@ -518,6 +518,9 @@ TEST_F(FileTest, CastFlatConversionLiteralInitializer) { TEST_F(FileTest, CastFlatConversionDecomposeVector) { runFileTest("cast.flat-conversion.vector.hlsl"); } +TEST_F(FileTest, CastImplicitScalarToVec) { + runFileTest("cast.scalar-to-vec.implicit.hlsl", Expect::Failure); +} TEST_F(FileTest, CastExplicitVecToMat) { runFileTest("cast.vec-to-mat.explicit.hlsl"); }