summaryrefslogtreecommitdiff
path: root/src/mir/check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mir/check.cpp')
-rw-r--r--src/mir/check.cpp46
1 files changed, 40 insertions, 6 deletions
diff --git a/src/mir/check.cpp b/src/mir/check.cpp
index 186e93fb..0c428c64 100644
--- a/src/mir/check.cpp
+++ b/src/mir/check.cpp
@@ -14,6 +14,7 @@
void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type)
{
+ TRACE_FUNCTION_F(path);
Span sp;
::MIR::TypeResolve state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn };
// Validation rules:
@@ -107,6 +108,14 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
{
}
+ bool operator==(const ValStates& x) const {
+ if( ret_state != x.ret_state ) return false;
+ if( arguments != x.arguments ) return false;
+ if( temporaries != x.temporaries ) return false;
+ if( variables != x.variables ) return false;
+ return true;
+ }
+
bool empty() const {
return arguments.empty() && temporaries.empty() && variables.empty();
}
@@ -221,6 +230,15 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
};
::std::vector< ValStates> block_start_states( fcn.blocks.size() );
::std::vector< ::std::pair<unsigned int, ValStates> > to_visit_blocks;
+
+ auto add_to_visit = [&](auto idx, auto vs) {
+ for(const auto& b : to_visit_blocks)
+ if( b.first == idx && b.second == vs)
+ return ;
+ if( block_start_states.at(idx) == vs )
+ return ;
+ to_visit_blocks.push_back( ::std::make_pair(idx, mv$(vs)) );
+ };
to_visit_blocks.push_back( ::std::make_pair(0, ValStates{ args.size(), fcn.temporaries.size(), fcn.named_variables.size() }) );
while( to_visit_blocks.size() > 0 )
{
@@ -265,7 +283,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
val_state.ensure_valid(state, se.val);
),
(Cast,
- val_state.move_val(state, se.val);
+ // Well.. it's not exactly moved...
+ val_state.ensure_valid(state, se.val);
+ //val_state.move_val(state, se.val);
),
(BinOp,
val_state.move_val(state, se.val_l);
@@ -335,21 +355,35 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path
),
(Goto,
// Push block with the new state
- to_visit_blocks.push_back( ::std::make_pair(e, ::std::move(val_state)) );
+ add_to_visit( e, mv$(val_state) );
),
(Panic,
// What should be done here?
),
(If,
// Push blocks
- to_visit_blocks.push_back( ::std::make_pair(e.bb0, val_state) );
- to_visit_blocks.push_back( ::std::make_pair(e.bb1, ::std::move(val_state)) );
+ val_state.ensure_valid( state, e.cond );
+ add_to_visit( e.bb0, val_state );
+ add_to_visit( e.bb1, mv$(val_state) );
),
(Switch,
- // TODO: Push blocks
+ val_state.ensure_valid( state, e.val );
+ for(const auto& tgt : e.targets)
+ {
+ add_to_visit( tgt, val_state );
+ }
),
(Call,
- // TODO: Push blocks (with return valid only in one)
+ if( e.fcn.is_Value() )
+ val_state.ensure_valid( state, e.fcn.as_Value() );
+ for(const auto& arg : e.args)
+ val_state.ensure_valid( state, arg );
+ // Push blocks (with return valid only in one)
+ add_to_visit(e.panic_block, val_state);
+
+ // TODO: If the function returns !, don't follow the ret_block
+ val_state.mark_validity( state, e.ret_val, true );
+ add_to_visit(e.ret_block, mv$(val_state));
)
)
}