diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-18 13:24:43 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-18 13:24:43 +0800 |
commit | 48658d1621851fc1cda5fff397cfc380c0757b8e (patch) | |
tree | 7fbbc07b126982ce22f4be265ed08d21d86c139b | |
parent | 747bc2627450e8dc1bc04fb4e48e69a44cd5dd36 (diff) | |
download | mrust-48658d1621851fc1cda5fff397cfc380c0757b8e.tar.gz |
MIR Gen - Ensure that function return values are dropped
-rw-r--r-- | src/mir/from_hir.cpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 3 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 64 |
3 files changed, 42 insertions, 27 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 98d339e3..f014961a 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1452,6 +1452,8 @@ namespace { } else { + // NOTE: This has to be done here because the builder can't easily do it. + m_builder.mark_value_assigned(node.span(), res); } m_builder.set_result( node.span(), mv$(res) ); } diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index e7492df6..3fd933fc 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -156,6 +156,9 @@ public: return m_block_active; } + // Mark a value as initialised (used for Call, because it has to be done after the panic block is populated) + void mark_value_assigned(const Span& sp, const ::MIR::LValue& val); + void set_cur_block(unsigned int new_block); ::MIR::BasicBlockId pause_cur_block(); void end_block(::MIR::Terminator term); diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index d539ef89..86dde1ac 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -251,6 +251,37 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal ) // Drop target if populated + mark_value_assigned(sp, dst); + m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Assign({ mv$(dst), mv$(val) }) ); +} +void MirBuilder::push_stmt_drop(const Span& sp, ::MIR::LValue val) +{ + ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); + ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); + + if( lvalue_is_copy(sp, val) ) { + // Don't emit a drop for Copy values + return ; + } + + m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val) }) ); +} +void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val) +{ + ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); + ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); + + // TODO: Ensure that the type is a Box + //if( lvalue_is_copy(sp, val) ) { + // // Don't emit a drop for Copy values + // return ; + //} + + m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val) }) ); +} + +void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) +{ TU_MATCH_DEF(::MIR::LValue, (dst), (e), ( ), @@ -303,32 +334,6 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal set_variable_state(sp, e, VarState::Init); ) ) - m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Assign({ mv$(dst), mv$(val) }) ); -} -void MirBuilder::push_stmt_drop(const Span& sp, ::MIR::LValue val) -{ - ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); - ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); - - if( lvalue_is_copy(sp, val) ) { - // Don't emit a drop for Copy values - return ; - } - - m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::DEEP, mv$(val) }) ); -} -void MirBuilder::push_stmt_drop_shallow(const Span& sp, ::MIR::LValue val) -{ - ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); - ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); - - // TODO: Ensure that the type is a Box - //if( lvalue_is_copy(sp, val) ) { - // // Don't emit a drop for Copy values - // return ; - //} - - m_output.blocks.at(m_current_block).statements.push_back( ::MIR::Statement::make_Drop({ ::MIR::eDropKind::SHALLOW, mv$(val) }) ); } void MirBuilder::set_cur_block(unsigned int new_block) @@ -412,7 +417,7 @@ ScopeHandle MirBuilder::new_scope_loop(const Span& sp) } void MirBuilder::terminate_scope(const Span& sp, ScopeHandle scope, bool emit_cleanup/*=true*/) { - DEBUG("DONE scope " << scope.idx); + DEBUG("DONE scope " << scope.idx << " - " << (emit_cleanup ? "CLEANUP" : "NO CLEANUP")); // 1. Check that this is the current scope (at the top of the stack) if( m_scope_stack.empty() || m_scope_stack.back() != scope.idx ) { @@ -989,8 +994,13 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd) switch( get_temp_state(sd.span, tmp_idx) ) { case VarState::Uninit: + DEBUG("Temporary " << tmp_idx << " Uninit"); + break; case VarState::Dropped: + DEBUG("Temporary " << tmp_idx << " Dropped"); + break; case VarState::Moved: + DEBUG("Temporary " << tmp_idx << " Moved"); break; case VarState::Init: push_stmt_drop( sd.span, ::MIR::LValue::make_Temporary({ tmp_idx }) ); |