summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-09-26 15:40:22 -0400
committerGitHub <noreply@github.com>2023-09-26 12:40:22 -0700
commita18dca27392b257ba2cc58ceabdf15471f34ee25 (patch)
treee76ed8fa4fbdc3f9fa3e0ea4f1b45bde64b57eab
parent6c991942ac4ec2e2abf6abe73a2429183172af84 (diff)
Fix for epoch/ASTBuilder* nullptr issue (#3240)
* Fix issue with failing tests tests/serialization/serialized-module-test.slang tests/serialization/extern/extern-test.slang * Fix issue with session destruction order on Session. * Improve comment.
-rw-r--r--source/slang/slang-ast-base.cpp11
-rw-r--r--source/slang/slang-serialize-ast.cpp2
-rw-r--r--source/slang/slang-serialize-container.cpp3
-rw-r--r--source/slang/slang.cpp7
4 files changed, 19 insertions, 4 deletions
diff --git a/source/slang/slang-ast-base.cpp b/source/slang/slang-ast-base.cpp
index 7fa0a8886..60be7a563 100644
--- a/source/slang/slang-ast-base.cpp
+++ b/source/slang/slang-ast-base.cpp
@@ -22,11 +22,14 @@ void NodeBase::_initDebug(ASTNodeType inAstNodeType, ASTBuilder* inAstBuilder)
}
DeclRefBase* Decl::getDefaultDeclRef()
{
- auto astBuilder = getCurrentASTBuilder();
- if (astBuilder && astBuilder->getEpoch() != m_defaultDeclRefEpoch || !m_defaultDeclRef)
+ if (auto astBuilder = getCurrentASTBuilder())
{
- m_defaultDeclRef = astBuilder->getOrCreate<DirectDeclRef>(this);
- m_defaultDeclRefEpoch = astBuilder->getEpoch();
+ const Index currentEpoch = astBuilder->getEpoch();
+ if (currentEpoch != m_defaultDeclRefEpoch || !m_defaultDeclRef)
+ {
+ m_defaultDeclRef = astBuilder->getOrCreate<DirectDeclRef>(this);
+ m_defaultDeclRefEpoch = currentEpoch;
+ }
}
return m_defaultDeclRef;
}
diff --git a/source/slang/slang-serialize-ast.cpp b/source/slang/slang-serialize-ast.cpp
index b51775710..2465de812 100644
--- a/source/slang/slang-serialize-ast.cpp
+++ b/source/slang/slang-serialize-ast.cpp
@@ -86,6 +86,8 @@ struct ASTFieldAccess
ASTBuilder builder(sharedASTBuilder, "Serialize Check");
+ SetASTBuilderContextRAII astBuilderRAII(&builder);
+
DefaultSerialObjectFactory objectFactory(&builder);
// We could now check that the loaded data matches
diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp
index 263abf465..175f970c9 100644
--- a/source/slang/slang-serialize-container.cpp
+++ b/source/slang/slang-serialize-container.cpp
@@ -390,6 +390,9 @@ static List<ExtensionDecl*>& _getCandidateExtensionList(
astBuilder = new ASTBuilder(options.sharedASTBuilder, buf.produceString());
}
+ /// We need to make the current ASTBuilder available for access via thread_local global.
+ SetASTBuilderContextRAII astBuilderRAII(astBuilder);
+
DefaultSerialObjectFactory objectFactory(astBuilder);
SerialReader reader(serialClasses, &objectFactory);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 38ebcccd6..46ccb6ce9 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4726,6 +4726,13 @@ void Session::addBuiltinSource(
Session::~Session()
{
+ // This is necessary because this ASTBuilder uses the SharedASTBuilder also owned by the session.
+ // If the SharedASTBuilder gets dtored before the globalASTBuilder it has a dangling pointer, which
+ // is referenced in the ASTBuilder dtor (likely) causing a crash.
+ //
+ // By destroying first we know it is destroyed, before the SharedASTBuilder.
+ globalAstBuilder.setNull();
+
// destroy modules next
stdlibModules = decltype(stdlibModules)();
}