summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-10-19 12:05:18 -0400
committerGitHub <noreply@github.com>2020-10-19 09:05:18 -0700
commitacf94e79250c258e1969be7ece9cb7ccdecbe099 (patch)
tree3f9f1b25dab56ebe918fcbdd46e6a557f3d6af7e /source
parentd3e255b31b39c9a8979a60023269567078d9dce3 (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')
-rw-r--r--source/slang/slang-check-decl.cpp33
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);