summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarsh Aggarwal (NVIDIA) <haaggarwal@nvidia.com>2025-06-05 13:44:06 +0530
committerGitHub <noreply@github.com>2025-06-05 08:14:06 +0000
commit624770a1e1ba7747cd7b2f5e0def1d677e931c8c (patch)
treec7bdb4e2087c8055d4b3ef1d9dbc79c176ff3ef3
parent0c4c63b4a575f45f5dcf03f26b78becd36b0efca (diff)
Fix crash when loading modules with syntax errors (#6993) (#7288)
* Fix#6993 - Emit Diagnostic Warning and Fix SIGSEGV * Update external/slang-rhi submodule * Add checks for valid stage names for paq in SemanticsVisitor check * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
m---------external/slang-rhi0
-rw-r--r--source/core/slang-dictionary.h3
-rw-r--r--source/slang/slang-check-modifier.cpp42
-rw-r--r--source/slang/slang-diagnostic-defs.h6
-rw-r--r--source/slang/slang.cpp3
-rw-r--r--tests/diagnostics/invalid-paq-stage-names.slang14
6 files changed, 66 insertions, 2 deletions
diff --git a/external/slang-rhi b/external/slang-rhi
-Subproject 00de1d7c04d64f7cac99ce0780e492c8c67ebd0
+Subproject c33a2ec9b3257bfa908f6f3d19e38cc067cb251
diff --git a/source/core/slang-dictionary.h b/source/core/slang-dictionary.h
index d35255a8c..b3aa354d2 100644
--- a/source/core/slang-dictionary.h
+++ b/source/core/slang-dictionary.h
@@ -339,6 +339,7 @@ protected:
DictionaryType dict;
private:
+ void init() {} // Base case for recursion
template<typename... Args>
void init(const T& v, Args... args)
{
@@ -406,6 +407,8 @@ public:
template<typename T>
class HashSet : public HashSetBase<T, Dictionary<T, _DummyClass>>
{
+public:
+ using HashSetBase<T, Dictionary<T, _DummyClass>>::HashSetBase;
};
template<typename TKey, typename TValue>
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 900f503db..e5249ac88 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -2211,6 +2211,9 @@ void SemanticsVisitor::checkRayPayloadStructFields(StructDecl* structDecl)
return;
}
+ // Define valid stage names
+ const HashSet<String> validStages("anyhit", "closesthit", "miss", "caller");
+
// Check each field in the struct
for (auto member : structDecl->members)
{
@@ -2220,8 +2223,11 @@ void SemanticsVisitor::checkRayPayloadStructFields(StructDecl* structDecl)
continue;
}
- bool hasReadModifier = fieldVarDecl->findModifier<RayPayloadReadSemantic>() != nullptr;
- bool hasWriteModifier = fieldVarDecl->findModifier<RayPayloadWriteSemantic>() != nullptr;
+ auto readModifier = fieldVarDecl->findModifier<RayPayloadReadSemantic>();
+ auto writeModifier = fieldVarDecl->findModifier<RayPayloadWriteSemantic>();
+
+ bool hasReadModifier = readModifier != nullptr;
+ bool hasWriteModifier = writeModifier != nullptr;
if (!hasReadModifier && !hasWriteModifier)
{
@@ -2231,6 +2237,38 @@ void SemanticsVisitor::checkRayPayloadStructFields(StructDecl* structDecl)
Diagnostics::rayPayloadFieldMissingAccessQualifiers,
fieldVarDecl->getName());
}
+
+ // Check stage names in read qualifier
+ if (readModifier)
+ {
+ for (auto& stageToken : readModifier->stageNameTokens)
+ {
+ String stageName = stageToken.getContent();
+ if (!validStages.contains(stageName))
+ {
+ getSink()->diagnose(
+ stageToken,
+ Diagnostics::rayPayloadInvalidStageInAccessQualifier,
+ stageName);
+ }
+ }
+ }
+
+ // Check stage names in write qualifier
+ if (writeModifier)
+ {
+ for (auto& stageToken : writeModifier->stageNameTokens)
+ {
+ String stageName = stageToken.getContent();
+ if (!validStages.contains(stageName))
+ {
+ getSink()->diagnose(
+ stageToken,
+ Diagnostics::rayPayloadInvalidStageInAccessQualifier,
+ stageName);
+ }
+ }
+ }
}
}
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 3786a0cf3..bef32e20e 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -2896,5 +2896,11 @@ DIAGNOSTIC(
Error,
rayPayloadFieldMissingAccessQualifiers,
"field '$0' in ray payload struct must have either 'read' OR 'write' access qualifiers")
+DIAGNOSTIC(
+ 40001,
+ Error,
+ rayPayloadInvalidStageInAccessQualifier,
+ "invalid stage name '$0' in ray payload access qualifier; valid stages are 'anyhit', "
+ "'closesthit', 'miss', and 'caller'")
#undef DIAGNOSTIC
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 912cd2e10..d8879c690 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4182,6 +4182,9 @@ void Linkage::loadParsedModule(
if (errorCountAfter != errorCountBefore)
{
// There must have been an error in the loaded module.
+ // Remove from maps if there were errors during semantic checking
+ mapPathToLoadedModule.remove(mostUniqueIdentity);
+ mapNameToLoadedModules.remove(name);
}
else
{
diff --git a/tests/diagnostics/invalid-paq-stage-names.slang b/tests/diagnostics/invalid-paq-stage-names.slang
new file mode 100644
index 000000000..8547b7d5a
--- /dev/null
+++ b/tests/diagnostics/invalid-paq-stage-names.slang
@@ -0,0 +1,14 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target hlsl
+
+// CHECK: ([[# @LINE+3]]): error 40001:
+struct [raypayload] ValidRayPayload
+{
+ float4 color : read(anyht, closesthit, miss) : write(caller);
+};
+
+[shader("raygeneration")]
+void rayGenShader()
+{
+ ValidRayPayload payload;
+ // Just a placeholder function to avoid unused struct warning
+}