diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2020-10-19 12:05:18 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-19 09:05:18 -0700 |
| commit | acf94e79250c258e1969be7ece9cb7ccdecbe099 (patch) | |
| tree | 3f9f1b25dab56ebe918fcbdd46e6a557f3d6af7e /source/slang/slang-check-decl.cpp | |
| parent | d3e255b31b39c9a8979a60023269567078d9dce3 (diff) | |
Hotfix: Crash due to ContainerDecl->members being altered whislt iterated over (#1580)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Access the members iteration in _ensureAllDeclsRec via indices to avoid a change in the array invalidating the list.
* Fix another iterator of members in SemanticVisitor
* Slight improvements to comments - main purpose is to kick a new build.
Diffstat (limited to 'source/slang/slang-check-decl.cpp')
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index a51dc0313..0735f4620 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -783,14 +783,23 @@ namespace Slang // If `decl` is a container, then we want to ensure its children. if(auto containerDecl = as<ContainerDecl>(decl)) - { - // As an exception, if any of the child is a `ScopeDecl`, - // then that indicates that it represents a scope for local - // declarations under a statement (e.g., in a function body), - // and we don't want to check such local declarations here. - // - for(auto childDecl : containerDecl->members) + { + // NOTE! We purposefully do not iterate with the for(auto childDecl : containerDecl->members) here, + // because the visitor may add to `members` whilst iteration takes place, invalidating the iterator + // and likely a crash. + // + // Accessing the members via index side steps the issue. + const auto& members = containerDecl->members; + for(Index i = 0; i < members.getCount(); ++i) { + Decl* childDecl = members[i]; + + // As an exception, if any of the child is a `ScopeDecl`, + // then that indicates that it represents a scope for local + // declarations under a statement (e.g., in a function body), + // and we don't want to check such local declarations here. + // + if(as<ScopeDecl>(childDecl)) continue; @@ -1126,8 +1135,16 @@ namespace Slang { genericDecl->setCheckState(DeclCheckState::ReadyForLookup); - for (auto m : genericDecl->members) + // NOTE! We purposefully do not iterate with the for(auto m : genericDecl->members) here, + // because the visitor may add to `members` whilst iteration takes place, invalidating the iterator + // and likely a crash. + // + // Accessing the members via index side steps the issue. + const auto& members = genericDecl->members; + for (Index i = 0; i < members.getCount(); ++i) { + Decl* m = members[i]; + if (auto typeParam = as<GenericTypeParamDecl>(m)) { ensureDecl(typeParam, DeclCheckState::ReadyForReference); |
