diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3d61484b31..9993a54ca6 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7884,6 +7884,10 @@ def err_hlsl_node_record_object : Error< "object %0 may not appear in a node record">; def err_hlsl_array_disallowed : Error< "%select{entry parameter|declaration}1 of type %0 may not be an array">; +def err_hlsl_inputpatch_size: Error< + "InputPatch element count must be greater than 0">; +def err_hlsl_outputpatch_size: Error< + "OutputPatch element count must be greater than 0">; def note_hlsl_node_array : Note<"'%0' cannot be used as an array; did you mean '%0Array'?">; // HLSL Change Ends diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 7dc479166d..d76943b877 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -15138,12 +15138,30 @@ void DiagnoseMeshEntry(Sema &S, FunctionDecl *FD, llvm::StringRef StageName) { return; } +void DiagnoseDomainEntry(Sema &S, FunctionDecl *FD, llvm::StringRef StageName) { + for (const auto *param : FD->params()) { + if (!hlsl::IsHLSLOutputPatchType(param->getType())) + continue; + if (hlsl::GetHLSLInputPatchCount(param->getType()) > 0) + continue; + S.Diags.Report(param->getLocation(), diag::err_hlsl_inputpatch_size); + } + return; +} + void DiagnoseHullEntry(Sema &S, FunctionDecl *FD, llvm::StringRef StageName) { HLSLPatchConstantFuncAttr *Attr = FD->getAttr(); if (!Attr) S.Diags.Report(FD->getLocation(), diag::err_hlsl_missing_attr) << StageName << "patchconstantfunc"; + for (const auto *param : FD->params()) { + if (!hlsl::IsHLSLInputPatchType(param->getType())) + continue; + if (hlsl::GetHLSLInputPatchCount(param->getType()) > 0) + continue; + S.Diags.Report(param->getLocation(), diag::err_hlsl_inputpatch_size); + } return; } @@ -15570,7 +15588,6 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { switch (Stage) { case DXIL::ShaderKind::Pixel: case DXIL::ShaderKind::Vertex: - case DXIL::ShaderKind::Domain: case DXIL::ShaderKind::Library: case DXIL::ShaderKind::Invalid: return; @@ -15580,6 +15597,8 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { case DXIL::ShaderKind::Mesh: { return DiagnoseMeshEntry(S, FD, StageName); } + case DXIL::ShaderKind::Domain: + return DiagnoseDomainEntry(S, FD, StageName); case DXIL::ShaderKind::Hull: { return DiagnoseHullEntry(S, FD, StageName); } diff --git a/tools/clang/test/CodeGenHLSL/ds-error-outputpatch-size.hlsl b/tools/clang/test/CodeGenHLSL/ds-error-outputpatch-size.hlsl new file mode 100644 index 0000000000..d68b5fcf14 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/ds-error-outputpatch-size.hlsl @@ -0,0 +1,11 @@ +// RUN: not %dxc -T ds_6_0 -E main %s 2>&1 | FileCheck %s + +struct ControlPoint { + float position : MY_BOOL; +}; + +ControlPoint main(const OutputPatch patch) { + // CHECK: error: OutputPatch element count must be greater than 0 + return patch[0]; +} + diff --git a/tools/clang/test/CodeGenHLSL/hs-error-inputpatch-size.hlsl b/tools/clang/test/CodeGenHLSL/hs-error-inputpatch-size.hlsl new file mode 100644 index 0000000000..892ca7d216 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/hs-error-inputpatch-size.hlsl @@ -0,0 +1,22 @@ +// RUN: not %dxc -T hs_6_0 -E main %s 2>&1 | FileCheck %s + +struct ControlPoint { + float position : MY_BOOL; +}; + +struct PatchData { + float edge [3] : SV_TessFactor; + float inside : SV_InsideTessFactor; +}; + +PatchData HullConst () { return (PatchData)0; } + +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[patchconstantfunc("HullConst")] +[outputcontrolpoints(3)] +ControlPoint main(InputPatch v, uint id : SV_OutputControlPointID) { + // CHECK: error: InputPatch element count must be greater than 0 + return v[id]; +}