summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-18 13:24:43 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-18 13:24:43 +0800
commit48658d1621851fc1cda5fff397cfc380c0757b8e (patch)
tree7fbbc07b126982ce22f4be265ed08d21d86c139b
parent747bc2627450e8dc1bc04fb4e48e69a44cd5dd36 (diff)
downloadmrust-48658d1621851fc1cda5fff397cfc380c0757b8e.tar.gz
MIR Gen - Ensure that function return values are dropped
-rw-r--r--src/mir/from_hir.cpp2
-rw-r--r--src/mir/from_hir.hpp3
-rw-r--r--src/mir/mir_builder.cpp64
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 }) );