mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 10:44:41 +01:00
Fix crash from accessing a Check::Context during lowering (#7335)
In generate_ast.cpp, an `CarbonExternalASTSource` is installed that has a `Check::Context` pointer. During lowering, this `ExternalASTSource` is still installed, and using it can cause a crash if the now-invalid pointer is dereferenced. Fix by adding a new `ReadOnlyASTSource` in sem_ir, and using that during lowering. `CarbonExternalASTSource` now inherits from `ReadOnlyASTSource` to avoid some code duplication. In generate_ast.cpp, we now always install a multiplex source, even if there's only one child source. Clang internally keeps pointers to the top-level `ExternalASTSource` installed via `setExternalSource`, and those pointers aren't updated if `setExternalSource` is called again. By using `MultiplexExternalSemaSource`, we can keep the top-level `ExternalASTSource` pointer the same, and only update its children. Using `MultiplexExternalSemaSource` this way requires a new constructor and a method to modify its child sources; added a new LLVM patch adding those. https://github.com/carbon-language/carbon-lang/issues/7142
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include "toolchain/lower/context.h"
|
||||
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Sema/MultiplexExternalSemaSource.h"
|
||||
#include "common/check.h"
|
||||
#include "common/growing_range.h"
|
||||
#include "common/raw_string_ostream.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
||||
#include "toolchain/lower/file_context.h"
|
||||
#include "toolchain/sem_ir/inst_namer.h"
|
||||
#include "toolchain/sem_ir/read_only_ast_source.h"
|
||||
|
||||
namespace Carbon::Lower {
|
||||
|
||||
@@ -70,6 +72,23 @@ auto Context::Finalize() && -> std::unique_ptr<llvm::Module> {
|
||||
|
||||
for (auto& file_context : file_contexts_.values()) {
|
||||
if (file_context) {
|
||||
if (file_context->cpp_file()) {
|
||||
// Remove the `CarbonExternalASTSource` installed during check
|
||||
// (always the last child of the multiplex source) and replace
|
||||
// it with a `ReadOnlyASTSource`. This is necessary because the
|
||||
// original source has a now-invalid pointer to a
|
||||
// `Check::Context`.
|
||||
auto& ast = const_cast<clang::ASTContext&>(
|
||||
file_context->cpp_file()->ast_context());
|
||||
auto* multiplex_source =
|
||||
cast<clang::MultiplexExternalSemaSource>(ast.getExternalSource());
|
||||
auto& child_sources = multiplex_source->GetSources();
|
||||
child_sources.pop_back();
|
||||
multiplex_source->AddSource(
|
||||
llvm::makeIntrusiveRefCnt<SemIR::ReadOnlyASTSource>(
|
||||
file_context->sem_ir()));
|
||||
}
|
||||
|
||||
file_context->Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user