summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-check-shader.cpp44
-rw-r--r--source/slang/slang-diagnostic-defs.h6
-rw-r--r--tests/diagnostics/entry-point-mod-errors.slang22
3 files changed, 72 insertions, 0 deletions
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index 29134131c..ed62e948d 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -531,6 +531,50 @@ void validateEntryPoint(EntryPoint* entryPoint, DiagnosticSink* sink)
}
}
+ // Attribute and keyword diagnostics. Check for the [[vk::binding]] and [[vk::push_constants]]
+ // attributes, and the register() and packoffset() keywords on entry point parameters. Slang
+ // currently ignores these, which can lead to user confusion whenever the output does not
+ // correspond to what was requested. Conversely, Slang silently generating output that just
+ // happens to align with what's requested can also lead to user confusion, with the user
+ // mistakenly believing that the modifiers are working as intended.
+ //
+ // Note that this only checks when they're used on entry point parameters.
+ for (const auto& param : entryPointFuncDecl->getParameters())
+ {
+ if (param->findModifier<GLSLBindingAttribute>())
+ {
+ sink->diagnose(
+ param,
+ Diagnostics::unhandledModOnEntryPointParameter,
+ "attribute '[[vk::binding(...)]]'",
+ param->getName());
+ }
+ if (param->findModifier<PushConstantAttribute>())
+ {
+ sink->diagnose(
+ param,
+ Diagnostics::unhandledModOnEntryPointParameter,
+ "attribute '[[vk::push_constant]]'",
+ param->getName());
+ }
+ if (param->findModifier<HLSLRegisterSemantic>())
+ {
+ sink->diagnose(
+ param,
+ Diagnostics::unhandledModOnEntryPointParameter,
+ "keyword 'register'",
+ param->getName());
+ }
+ if (param->findModifier<HLSLPackOffsetSemantic>())
+ {
+ sink->diagnose(
+ param,
+ Diagnostics::unhandledModOnEntryPointParameter,
+ "keyword 'packoffset'",
+ param->getName());
+ }
+ }
+
for (auto target : linkage->targets)
{
auto targetCaps = target->getTargetCaps();
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 08e852547..6d9f7faab 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -2077,6 +2077,12 @@ DIAGNOSTIC(
"expected a constant value of type '$0' as argument for specialization parameter '$1'")
DIAGNOSTIC(
+ 38010,
+ Warning,
+ unhandledModOnEntryPointParameter,
+ "$0 on parameter '$1' is unsupported on entry point parameters and will be ignored")
+
+DIAGNOSTIC(
38100,
Error,
typeDoesntImplementInterfaceRequirement,
diff --git a/tests/diagnostics/entry-point-mod-errors.slang b/tests/diagnostics/entry-point-mod-errors.slang
new file mode 100644
index 000000000..090ce5e33
--- /dev/null
+++ b/tests/diagnostics/entry-point-mod-errors.slang
@@ -0,0 +1,22 @@
+// Test to check if we emit a warning when unhandled modifiers are applied to
+// entry point parameters.
+
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -entry computeMain -target cuda
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -entry computeMain -target metal
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -entry computeMain -target cpp
+[shader("compute")]
+[numthreads(1,1,1)]
+void computeMain(
+// CHECK: ([[#@LINE+1]]): warning 38010: {{.*}}vk::binding
+ [[vk::binding(5, 4)]] RWStructuredBuffer<uint> test1,
+// CHECK: ([[#@LINE+1]]): warning 38010: {{.*}}vk::push_constant
+ [[vk::push_constant]] RWStructuredBuffer<float> test2,
+// CHECK: ([[#@LINE+1]]): warning 38010: {{.*}}register
+ RWStructuredBuffer<float> test3 : register(r0),
+// CHECK: ([[#@LINE+1]]): warning 38010: {{.*}}packoffset
+ float test4 : packoffset(c4),
+ RWBuffer<float> output
+)
+{
+ output[0] = test2[0];
+}