[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:07:54 PDT 2026
https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/204152
>From 253dc77d5ba55c3a8c1b889b63f1f24b633efe00 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Tue, 16 Jun 2026 19:01:28 +0530
Subject: [PATCH 1/3] Fix module contamination after failed template
instantiation
---
clang/lib/Interpreter/IncrementalAction.cpp | 5 +++--
clang/lib/Interpreter/IncrementalAction.h | 2 ++
clang/lib/Interpreter/IncrementalParser.cpp | 4 +++-
.../recover-template-instantiation.cpp | 22 +++++++++++++++++++
4 files changed, 30 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..d9a7de25af147 100644
--- a/clang/lib/Interpreter/IncrementalAction.cpp
+++ b/clang/lib/Interpreter/IncrementalAction.cpp
@@ -53,7 +53,7 @@ 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 +114,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..0cf8564cc8fe2
--- /dev/null
+++ b/clang/test/Interpreter/recover-template-instantiation.cpp
@@ -0,0 +1,22 @@
+// 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.
+
+extern "C" int printf(const char *, ...);
+
+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;
+auto r = printf("x = %d\n", x);
+// CHECK: x = 10
+
+%quit
>From 28dc0848bc21fa756ff770cd0cf7086a4ff3d8d5 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Tue, 16 Jun 2026 19:10:35 +0530
Subject: [PATCH 2/3] code format
---
clang/lib/Interpreter/IncrementalAction.cpp | 3 ++-
clang/test/Interpreter/recover-template-instantiation.cpp | 5 +----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Interpreter/IncrementalAction.cpp b/clang/lib/Interpreter/IncrementalAction.cpp
index d9a7de25af147..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), LLVMCtx(LLVMCtx), Consumer(std::move(Consumer)) {}
+ Interp(I), CI(Instance), LLVMCtx(LLVMCtx), Consumer(std::move(Consumer)) {
+}
std::unique_ptr<ASTConsumer>
IncrementalAction::CreateASTConsumer(CompilerInstance & /*CI*/,
diff --git a/clang/test/Interpreter/recover-template-instantiation.cpp b/clang/test/Interpreter/recover-template-instantiation.cpp
index 0cf8564cc8fe2..97af217e1da50 100644
--- a/clang/test/Interpreter/recover-template-instantiation.cpp
+++ b/clang/test/Interpreter/recover-template-instantiation.cpp
@@ -7,10 +7,7 @@
extern "C" int printf(const char *, ...);
-template <typename T> T f(T a) {
- static_assert(sizeof(T) == 0, "unsupported type");
- return a;
-}
+template <typename T> T f(T a) { static_assert(sizeof(T) == 0, "unsupported type"); return a; }
f(1.0);
// CHECK: error: static assertion failed
>From 47914a42f739e04a1bcb925e4ef2c12042724296 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Mon, 22 Jun 2026 16:37:37 +0530
Subject: [PATCH 3/3] try fixing test failure
---
clang/test/Interpreter/recover-template-instantiation.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/clang/test/Interpreter/recover-template-instantiation.cpp b/clang/test/Interpreter/recover-template-instantiation.cpp
index 97af217e1da50..7f67ef5f131f8 100644
--- a/clang/test/Interpreter/recover-template-instantiation.cpp
+++ b/clang/test/Interpreter/recover-template-instantiation.cpp
@@ -5,15 +5,13 @@
// instantiation error. The failed cell must not contaminate the CodeGen module
// used by subsequent cells.
-extern "C" int printf(const char *, ...);
-
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;
-auto r = printf("x = %d\n", x);
-// CHECK: x = 10
+x
+// CHECK: (int) 10
%quit
More information about the cfe-commits
mailing list