From 624770a1e1ba7747cd7b2f5e0def1d677e931c8c Mon Sep 17 00:00:00 2001 From: "Harsh Aggarwal (NVIDIA)" Date: Thu, 5 Jun 2025 13:44:06 +0530 Subject: 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 --- external/slang-rhi | 2 +- source/core/slang-dictionary.h | 3 ++ source/slang/slang-check-modifier.cpp | 42 +++++++++++++++++++++++-- source/slang/slang-diagnostic-defs.h | 6 ++++ source/slang/slang.cpp | 3 ++ tests/diagnostics/invalid-paq-stage-names.slang | 14 +++++++++ 6 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 tests/diagnostics/invalid-paq-stage-names.slang diff --git a/external/slang-rhi b/external/slang-rhi index 00de1d7c0..c33a2ec9b 160000 --- a/external/slang-rhi +++ b/external/slang-rhi @@ -1 +1 @@ -Subproject commit 00de1d7c04d64f7cac99ce0780e492c8c67ebd0b +Subproject commit c33a2ec9b3257bfa908f6f3d19e38cc067cb2511 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 void init(const T& v, Args... args) { @@ -406,6 +407,8 @@ public: template class HashSet : public HashSetBase> { +public: + using HashSetBase>::HashSetBase; }; template 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 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() != nullptr; - bool hasWriteModifier = fieldVarDecl->findModifier() != nullptr; + auto readModifier = fieldVarDecl->findModifier(); + auto writeModifier = fieldVarDecl->findModifier(); + + 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 +} -- cgit v1.2.3