From a18dca27392b257ba2cc58ceabdf15471f34ee25 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 26 Sep 2023 15:40:22 -0400 Subject: 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. --- source/slang/slang-ast-base.cpp | 11 +++++++---- source/slang/slang-serialize-ast.cpp | 2 ++ source/slang/slang-serialize-container.cpp | 3 +++ source/slang/slang.cpp | 7 +++++++ 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(this); - m_defaultDeclRefEpoch = astBuilder->getEpoch(); + const Index currentEpoch = astBuilder->getEpoch(); + if (currentEpoch != m_defaultDeclRefEpoch || !m_defaultDeclRef) + { + m_defaultDeclRef = astBuilder->getOrCreate(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& _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)(); } -- cgit v1.2.3