[clang] [clang-repl] Fix crashing on unusable top-level declarations (PR #230054)
Ivy Xu via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 8 03:39:58 PDT 2026
https://github.com/IvyXu420 created https://github.com/llvm/llvm-project/pull/230054
This is a regression from PR #150215.
After #150215, if R was an unusable statement (e.g., parsed from a top-level return statement), `R = Actions.ActOnNullStmt(Tok.getLocation());` updates the local variable R's value, but the value was never used.
This resulted in a null pointer dereference because `TLSD->setStmt()` was never called, leaving `TLSD->getStmt() == nullptr`.
This PR correctly sets the `TLSD.Statement`'s value when parsing unusable top-level declarations.
Fixes #229339.
>From 27c0546c666b43bd69603666d86698a63d7b5c23 Mon Sep 17 00:00:00 2001
From: Ivy Xu <fakeshadow1337 at gmail.com>
Date: Thu, 8 Oct 2026 17:52:21 +0800
Subject: [PATCH] Fix clang-repl crashing on unusable top-level declarations
---
clang/lib/Parse/ParseDecl.cpp | 4 +++-
clang/unittests/Interpreter/InterpreterTest.cpp | 14 ++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index fbecae7b80fb97..a984e1c7ee7d2d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5840,8 +5840,10 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() {
TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(getCurScope());
StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
- if (!R.isUsable())
+ if (!R.isUsable()) {
R = Actions.ActOnNullStmt(Tok.getLocation());
+ TLSD->setStmt(R.get());
+ }
if (Tok.is(tok::annot_repl_input_end) &&
Tok.getAnnotationValue() != nullptr) {
diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp b/clang/unittests/Interpreter/InterpreterTest.cpp
index 3becd00c128205..8d7c75cdcaab87 100644
--- a/clang/unittests/Interpreter/InterpreterTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterTest.cpp
@@ -573,4 +573,18 @@ TEST_F(InterpreterTest, TranslationUnit_CanonicalDecl) {
sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl());
}
+TEST_F(InterpreterTest, UnusableTopLevelDecl) {
+ std::vector<const char *> Args;
+ std::unique_ptr<Interpreter> Interp = createInterpreter(Args);
+
+ Value V;
+
+ llvm::cantFail(Interp->ParseAndExecute("return;", &V));
+
+ EXPECT_FALSE(V.isValid());
+ EXPECT_FALSE(V.hasValue());
+ ASSERT_EQ(V.getKind(), Value::K_Unspecified);
+ EXPECT_FALSE(V.isManuallyAlloc());
+}
+
} // end anonymous namespace
More information about the cfe-commits
mailing list