summaryrefslogtreecommitdiff
path: root/src/mir/from_hir.cpp
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-13 14:05:03 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-13 14:05:03 +0800
commit4ca6e7bdbefa83f8701f1303b6acbfbec152bbf2 (patch)
tree0c3a9e59fb627322d3d9b41f4699871c65e822e5 /src/mir/from_hir.cpp
parent22e6d4807c7ffe646d43c700c5b045e606fbdc92 (diff)
downloadmrust-4ca6e7bdbefa83f8701f1303b6acbfbec152bbf2.tar.gz
MIR Gen - Correct bounds for assignment operator overloads
Diffstat (limited to 'src/mir/from_hir.cpp')
-rw-r--r--src/mir/from_hir.cpp78
1 files changed, 60 insertions, 18 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 79e20e50..ed405933 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -316,29 +316,16 @@ namespace {
const auto& ty_slot = node.m_slot->m_res_type;
const auto& ty_val = node.m_value->m_res_type;
- ASSERT_BUG(sp, ty_slot == ty_val, "Types must match for assignment - " << ty_slot << " != " << ty_val);
if( node.m_op != ::HIR::ExprNode_Assign::Op::None )
{
- TU_IFLET(::HIR::TypeRef::Data, ty_slot.m_data, Primitive, e,
- switch(e)
- {
- case ::HIR::CoreType::Char:
- case ::HIR::CoreType::Str:
- case ::HIR::CoreType::Bool:
- BUG(sp, "Unsupported type for op-assign - " << ty_slot);
- break;
- default:
- // Good.
- break;
- }
- )
- else {
- BUG(sp, "Unsupported type for op-assign - " << ty_slot);
- }
-
auto val_lv = m_builder.lvalue_or_temp( ty_val, mv$(val) );
+ ASSERT_BUG(sp, ty_slot.m_data.is_Primitive(), "Assignment operator overloads are only valid on primitives - ty_slot="<<ty_slot);
+ auto ty_slot_p = ty_slot.m_data.as_Primitive();
+ ASSERT_BUG(sp, ty_val.m_data.is_Primitive(), "Assignment operator overloads are only valid on primitives - ty_val="<<ty_val);
+ auto ty_val_p = ty_val.m_data.as_Primitive();
+
::MIR::RValue res;
#define _(v) ::HIR::ExprNode_Assign::Op::v
::MIR::eBinOp op;
@@ -350,30 +337,85 @@ namespace {
case _(Mul): op = ::MIR::eBinOp::MUL; if(0)
case _(Div): op = ::MIR::eBinOp::DIV; if(0)
;
+ ASSERT_BUG(sp, ty_slot == ty_val, "Types must match for assignment - " << ty_slot << " != " << ty_val);
+ switch(ty_slot_p)
+ {
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Char:
+ case ::HIR::CoreType::Bool:
+ BUG(sp, "Invalid type for numeric op-assignment - " << ty_slot);
+ default:
+ break;
+ }
// TODO: Overflow check
res = ::MIR::RValue::make_BinOp({ dst.clone(), op, mv$(val_lv) });
break;
case _(Mod):
+ ASSERT_BUG(sp, ty_slot == ty_val, "Types must match for assignment - " << ty_slot << " != " << ty_val);
+ switch(ty_slot_p)
+ {
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Char:
+ case ::HIR::CoreType::Bool:
+ BUG(sp, "Invalid type for numeric op-assignment - " << ty_slot);
+ default:
+ break;
+ }
+ // NOTE: No overflow check needed for %=
res = ::MIR::RValue::make_BinOp({ dst.clone(), ::MIR::eBinOp::MOD, mv$(val_lv) });
break;
case _(Xor): op = ::MIR::eBinOp::BIT_XOR; if(0)
case _(Or ): op = ::MIR::eBinOp::BIT_OR ; if(0)
case _(And): op = ::MIR::eBinOp::BIT_AND; if(0)
;
+ ASSERT_BUG(sp, ty_slot == ty_val, "Types must match for bitwise op-assignment - " << ty_slot << " != " << ty_val);
+ switch(ty_slot_p)
+ {
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Char:
+ case ::HIR::CoreType::F32:
+ case ::HIR::CoreType::F64:
+ BUG(sp, "Invalid type for bitwise op-assignment - " << ty_slot);
+ default:
+ break;
+ }
res = ::MIR::RValue::make_BinOp({ dst.clone(), op, mv$(val_lv) });
break;
case _(Shl): op = ::MIR::eBinOp::BIT_SHL; if(0)
case _(Shr): op = ::MIR::eBinOp::BIT_SHR; if(0)
;
+ switch(ty_slot_p)
+ {
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Char:
+ case ::HIR::CoreType::F32:
+ case ::HIR::CoreType::F64:
+ BUG(sp, "Invalid type for shift op-assignment - " << ty_slot);
+ default:
+ break;
+ }
+ switch(ty_val_p)
+ {
+ case ::HIR::CoreType::Str:
+ case ::HIR::CoreType::Char:
+ case ::HIR::CoreType::F32:
+ case ::HIR::CoreType::F64:
+ BUG(sp, "Invalid type for shift op-assignment - " << ty_val);
+ default:
+ break;
+ }
+ // TODO: Assert that both types are integer types (allowed to be non-equal)
// TODO: Overflow check
res = ::MIR::RValue::make_BinOp({ dst.clone(), op, mv$(val_lv) });
break;
}
+ #undef _
m_builder.push_stmt_assign(mv$(dst), mv$(res));
}
else
{
+ ASSERT_BUG(sp, ty_slot == ty_val, "Types must match for assignment - " << ty_slot << " != " << ty_val);
m_builder.push_stmt_assign(mv$(dst), mv$(val));
}
m_builder.set_result(node.span(), ::MIR::RValue::make_Tuple({}));