[clang] [clang-repl] Always clean up scope and context for TopLevelStmtDecl (PR #150215)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 23 06:13:48 PDT 2025


https://github.com/devajithvs updated https://github.com/llvm/llvm-project/pull/150215

>From 3111b1de80945e00b375dd32cbbbf33197897032 Mon Sep 17 00:00:00 2001
From: Devajith Valaparambil Sreeramaswamy
 <devajith.valaparambil.sreeramaswamy at cern.ch>
Date: Wed, 23 Jul 2025 14:15:13 +0200
Subject: [PATCH] [clang-repl] Always clean up scope and context for
 TopLevelStmtDecl

This fixes an issue introduced by llvm/llvm-project at 4b70d17, where
failing to pop compound scope, function scope info, and decl context
after a failed statement could lead to an inconsistent internal state.
---
 clang/lib/Parse/ParseDecl.cpp   | 3 +--
 clang/lib/Sema/SemaDecl.cpp     | 3 ++-
 clang/test/Interpreter/fail.cpp | 8 ++++++++
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 893ef02450921..e47caeb855d0c 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -5695,11 +5695,10 @@ Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() {
                                Scope::CompoundStmtScope);
   TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(getCurScope());
   StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
+  Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
   if (!R.isUsable())
     R = Actions.ActOnNullStmt(Tok.getLocation());
 
-  Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
-
   if (Tok.is(tok::annot_repl_input_end) &&
       Tok.getAnnotationValue() != nullptr) {
     ConsumeAnnotationToken();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index fd22e012ea8b0..6e6669886ba36 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20573,7 +20573,8 @@ TopLevelStmtDecl *Sema::ActOnStartTopLevelStmtDecl(Scope *S) {
 }
 
 void Sema::ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement) {
-  D->setStmt(Statement);
+  if (Statement)
+    D->setStmt(Statement);
   PopCompoundScope();
   PopFunctionScopeInfo();
   PopDeclContext();
diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp
index 633d92794325c..68ab2503e9e75 100644
--- a/clang/test/Interpreter/fail.cpp
+++ b/clang/test/Interpreter/fail.cpp
@@ -18,4 +18,12 @@ extern "C" int printf(const char *, ...);
 int i = 42;
 auto r1 = printf("i = %d\n", i);
 // CHECK: i = 42
+
+1aap = 42; // expected-error {{invalid digit 'a' in decimal constant}}
+1aap = 42; i = 5;
+// expected-error {{intended to fail the -verify test but not hit an assertion}}
+
+printf("i = %d\n", i);
+// CHECK: i = 42
+
 %quit



More information about the cfe-commits mailing list