diff options
| author | Harsh Aggarwal (NVIDIA) <haaggarwal@nvidia.com> | 2025-06-05 13:44:06 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-05 08:14:06 +0000 |
| commit | 624770a1e1ba7747cd7b2f5e0def1d677e931c8c (patch) | |
| tree | c7bdb4e2087c8055d4b3ef1d9dbc79c176ff3ef3 | |
| parent | 0c4c63b4a575f45f5dcf03f26b78becd36b0efca (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-rhi | 0 | ||||
| -rw-r--r-- | source/core/slang-dictionary.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 42 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 6 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 3 | ||||
| -rw-r--r-- | tests/diagnostics/invalid-paq-stage-names.slang | 14 |
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 +} |
