diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-06-08 11:22:36 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-06-08 11:22:36 +0800 |
commit | aa1998553ad87ca55870a84b7d2ee946b421ec65 (patch) | |
tree | 8921c79ff8082e376041b193f4318add5e80f56b /src | |
parent | f2fdba69bf483c3516550f99fb6179acd95c6edb (diff) | |
download | mrust-aa1998553ad87ca55870a84b7d2ee946b421ec65.tar.gz |
MIR Gen - Fix clobbering of value state when fields are reassigned
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/from_hir.hpp | 3 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 32 |
2 files changed, 14 insertions, 21 deletions
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index a1f9a10f..c29d6283 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -293,8 +293,7 @@ private: const VarState& get_slot_state(const Span& sp, unsigned int idx, SlotType type, unsigned int skip_count=0) const; VarState& get_slot_state_mut(const Span& sp, unsigned int idx, SlotType type); - VarState* get_val_state_mut_p(const Span& sp, const ::MIR::LValue& lv); - VarState& get_val_state_mut(const Span& sp, const ::MIR::LValue& lv); + VarState* get_val_state_mut_p(const Span& sp, const ::MIR::LValue& lv, bool expect_valid=false); void terminate_loop_early(const Span& sp, ScopeType::Data_Loop& sd_loop); diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index 8e87c523..96833609 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -288,11 +288,7 @@ void MirBuilder::push_stmt_assign(const Span& sp, ::MIR::LValue dst, ::MIR::RVal } ), (Cast, - // TODO: Does this actually move? - //if( !e.type.m_data.is_Borrow() ) - { - this->moved_lvalue(sp, e.val); - } + this->moved_lvalue(sp, e.val); ), (BinOp, switch(e.op) @@ -404,7 +400,7 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) ASSERT_BUG(sp, dst.m_wrappers.empty(), "Assignment to a component of the return value should be impossible."); return ; } - VarState* state_p = get_val_state_mut_p(sp, dst);; + VarState* state_p = get_val_state_mut_p(sp, dst, /*expect_valid=*/true); if( state_p ) { @@ -1947,7 +1943,7 @@ VarState& MirBuilder::get_slot_state_mut(const Span& sp, unsigned int idx, SlotT } } -VarState* MirBuilder::get_val_state_mut_p(const Span& sp, const ::MIR::LValue& lv) +VarState* MirBuilder::get_val_state_mut_p(const Span& sp, const ::MIR::LValue& lv, bool expect_valid/*=false*/) { TRACE_FUNCTION_F(lv); VarState* vs; @@ -1968,6 +1964,11 @@ VarState* MirBuilder::get_val_state_mut_p(const Span& sp, const ::MIR::LValue& l ) ) + if( expect_valid && vs->is_Valid() ) + { + return nullptr; + } + for(const auto& w : lv.m_wrappers) { auto& ivs = *vs; @@ -2104,17 +2105,6 @@ VarState* MirBuilder::get_val_state_mut_p(const Span& sp, const ::MIR::LValue& l } return vs; } -VarState& MirBuilder::get_val_state_mut(const Span& sp, const ::MIR::LValue& lv) -{ - auto rv_p = this->get_val_state_mut_p(sp, lv); - if( !rv_p ) - { - //BUG(sp, "Move out of index with non-Copy values - Partial move?"); - BUG(sp, "Move out of deref with non-Copy values - &move? - " << lv << " : " << FMT_CB(ss, this->with_val_type(sp, lv, [&](const auto& ty){ss<<ty;});) ); - } - return *rv_p; -} - void MirBuilder::drop_value_from_state(const Span& sp, const VarState& vs, ::MIR::LValue lv) { TRACE_FUNCTION_F(lv << " " << vs); @@ -2198,7 +2188,11 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd) void MirBuilder::moved_lvalue(const Span& sp, const ::MIR::LValue& lv) { if( !lvalue_is_copy(sp, lv) ) { - auto& vs = get_val_state_mut(sp, lv); + auto* vs_p = get_val_state_mut_p(sp, lv); + if( !vs_p ) { + ERROR(sp, E0000, "Attempting to move out of invalid slot - " << lv); + } + auto& vs = *vs_p; // TODO: If the current state is Optional, set the drop flag to 0 vs = VarState::make_Invalid(InvalidType::Moved); } |