diff options
3 files changed, 66 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp index 4e3c8002fbf..b66f9a6b891 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp @@ -50,6 +50,7 @@ PythonExceptionState::Acquire(bool restore_on_exit) m_type.Reset(PyRefType::Owned, py_type); m_value.Reset(PyRefType::Owned, py_value); m_traceback.Reset(PyRefType::Owned, py_traceback); + m_restore_on_exit = restore_on_exit; } void @@ -77,6 +78,15 @@ PythonExceptionState::Discard() m_traceback.Reset(); } +void +PythonExceptionState::Reset() +{ + if (m_restore_on_exit) + Restore(); + else + Discard(); +} + bool PythonExceptionState::HasErrorOccurred() { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h index 854276b1f6a..3cf24ffed00 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h @@ -30,6 +30,9 @@ class PythonExceptionState void Discard(); + void + Reset(); + static bool HasErrorOccurred(); diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp index 3d7941e83a0..a0a6f986cef 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp @@ -79,6 +79,33 @@ TEST_F(PythonExceptionStateTest, TestDiscardSemantics) EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); } +TEST_F(PythonExceptionStateTest, TestResetSemantics) +{ + PyErr_Clear(); + + // Resetting when auto-restore is true should restore. + RaiseException(); + PythonExceptionState error(true); + EXPECT_TRUE(error.IsError()); + EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); + error.Reset(); + EXPECT_FALSE(error.IsError()); + EXPECT_TRUE(PythonExceptionState::HasErrorOccurred()); + + PyErr_Clear(); + + // Resetting when auto-restore is false should discard. + RaiseException(); + PythonExceptionState error2(false); + EXPECT_TRUE(error2.IsError()); + EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); + error2.Reset(); + EXPECT_FALSE(error2.IsError()); + EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); + + PyErr_Clear(); +} + TEST_F(PythonExceptionStateTest, TestManualRestoreSemantics) { PyErr_Clear(); @@ -119,3 +146,29 @@ TEST_F(PythonExceptionStateTest, TestAutoRestoreSemantics) PyErr_Clear(); } + +TEST_F(PythonExceptionStateTest, TestAutoRestoreChanged) +{ + // Test that if we re-acquire with different auto-restore semantics, + // that the new semantics are respected. + PyErr_Clear(); + + RaiseException(); + PythonExceptionState error(false); + EXPECT_TRUE(error.IsError()); + + error.Reset(); + EXPECT_FALSE(error.IsError()); + EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); + + RaiseException(); + error.Acquire(true); + EXPECT_TRUE(error.IsError()); + EXPECT_FALSE(PythonExceptionState::HasErrorOccurred()); + + error.Reset(); + EXPECT_FALSE(error.IsError()); + EXPECT_TRUE(PythonExceptionState::HasErrorOccurred()); + + PyErr_Clear(); +}
\ No newline at end of file |