[clang] [clang-repl] Fix module contamination after failed template instantiation (PR #204152)
Anutosh Bhat via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 22 04:09:05 PDT 2026
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/204152
>From ef6f947625ee81aa81d00eaac1f6b596f9a1d8f8 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Tue, 16 Jun 2026 19:01:28 +0530
Subject: [PATCH] Fix module contamination after failed template instantiation
---
clang/lib/Interpreter/IncrementalAction.cpp | 6 ++++--
clang/lib/Interpreter/IncrementalAction.h | 2 ++
clang/lib/Interpreter/IncrementalParser.cpp | 4 +++-
.../recover-template-instantiation.cpp | 17 +++++++++++++++++
4 files changed, 26 insertions(+), 3 deletions(-)
create mode 100644 clang/test/Interpreter/recover-template-instantiation.cpp
diff --git a/clang/lib/Interpreter/IncrementalAction.cpp b/clang/lib/Interpreter/IncrementalAction.cpp
index d22031c8fa893..f6bd75a5d90ed 100644
--- a/clang/lib/Interpreter/IncrementalAction.cpp
+++ b/clang/lib/Interpreter/IncrementalAction.cpp
@@ -53,7 +53,8 @@ IncrementalAction::IncrementalAction(CompilerInstance &Instance,
}
return Act;
}()),
- Interp(I), CI(Instance), Consumer(std::move(Consumer)) {}
+ Interp(I), CI(Instance), LLVMCtx(LLVMCtx), Consumer(std::move(Consumer)) {
+}
std::unique_ptr<ASTConsumer>
IncrementalAction::CreateASTConsumer(CompilerInstance & /*CI*/,
@@ -114,7 +115,8 @@ std::unique_ptr<llvm::Module> IncrementalAction::GenModule() {
CachedInCodeGenModule->ifunc_empty())) &&
"CodeGen wrote to a readonly module");
std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
- CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
+ CG->StartModule("incr_module_" + std::to_string(ID++),
+ M ? M->getContext() : LLVMCtx);
return M;
}
return nullptr;
diff --git a/clang/lib/Interpreter/IncrementalAction.h b/clang/lib/Interpreter/IncrementalAction.h
index 725cdd0c27cf4..27daf15d8c91e 100644
--- a/clang/lib/Interpreter/IncrementalAction.h
+++ b/clang/lib/Interpreter/IncrementalAction.h
@@ -13,6 +13,7 @@
#include "clang/Frontend/MultiplexConsumer.h"
namespace llvm {
+class LLVMContext;
class Module;
}
@@ -35,6 +36,7 @@ class IncrementalAction : public WrapperFrontendAction {
bool IsTerminating = false;
Interpreter &Interp;
[[maybe_unused]] CompilerInstance &CI;
+ llvm::LLVMContext &LLVMCtx;
std::unique_ptr<ASTConsumer> Consumer;
/// When CodeGen is created the first llvm::Module gets cached in many places
diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index f6d2779d64b2b..b3af640f3cb21 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -85,7 +85,9 @@ IncrementalParser::ParseOrWrapTopLevelDecl() {
DiagnosticsEngine &Diags = S.getDiagnostics();
if (Diags.hasErrorOccurred()) {
CleanUpPTU(C.getTranslationUnitDecl());
-
+ // Discard any partial CodeGen state to avoid contaminating the next cell.
+ Consumer->HandleTranslationUnit(C);
+ Act->GenModule();
Diags.Reset(/*soft=*/true);
Diags.getClient()->clear();
return llvm::make_error<llvm::StringError>("Parsing failed.",
diff --git a/clang/test/Interpreter/recover-template-instantiation.cpp b/clang/test/Interpreter/recover-template-instantiation.cpp
new file mode 100644
index 0000000000000..7f67ef5f131f8
--- /dev/null
+++ b/clang/test/Interpreter/recover-template-instantiation.cpp
@@ -0,0 +1,17 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl 2>&1 | FileCheck %s
+
+// Verify that clang-repl recovers cleanly after a deferred template
+// instantiation error. The failed cell must not contaminate the CodeGen module
+// used by subsequent cells.
+
+template <typename T> T f(T a) { static_assert(sizeof(T) == 0, "unsupported type"); return a; }
+
+f(1.0);
+// CHECK: error: static assertion failed
+
+int x = 10;
+x
+// CHECK: (int) 10
+
+%quit
More information about the cfe-commits
mailing list