llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ivy Xu (IvyXu420)

<details>
<summary>Changes</summary>

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-&gt;setStmt()` was 
never called, leaving `TLSD-&gt;getStmt() == nullptr`.

This PR correctly sets the `TLSD.Statement`'s value when parsing unusable 
top-level declarations.

Fixes #<!-- -->229339.

---
Full diff: https://github.com/llvm/llvm-project/pull/230054.diff


2 Files Affected:

- (modified) clang/lib/Parse/ParseDecl.cpp (+3-1) 
- (modified) clang/unittests/Interpreter/InterpreterTest.cpp (+14) 


``````````diff
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index fbecae7b80fb9..a984e1c7ee7d2 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 3becd00c12820..8d7c75cdcaab8 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

``````````

</details>


https://github.com/llvm/llvm-project/pull/230054
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to