diff options
-rw-r--r-- | src/trans/codegen_c.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index de246232..9580f7f5 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -60,6 +60,14 @@ namespace { << "\n" << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n" << "\n" + << "int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n" + << "\tint rv = memcmp(l.PTR, r.PTR, l.META < r.META ? l.META : r.META);\n" + << "\tif(rv != 0) return rv;\n" + << "\tif(l.META < r.META) return -1;\n" + << "\tif(l.META > r.META) return 1;\n" + << "\treturn 0;\n" + << "}\n" + << "\n" ; } @@ -1270,6 +1278,25 @@ namespace { (BinOp, emit_lvalue(e.dst); m_of << " = "; + ::HIR::TypeRef tmp; + const auto& ty = mir_res.get_lvalue_type(tmp, ve.val_l); + if( ty.m_data.is_Borrow() ) { + m_of << "(slice_cmp("; emit_lvalue(ve.val_l); m_of << ", "; emit_lvalue(ve.val_l); m_of << ")"; + switch(ve.op) + { + case ::MIR::eBinOp::EQ: m_of << " == 0"; break; + case ::MIR::eBinOp::NE: m_of << " != 0"; break; + case ::MIR::eBinOp::GT: m_of << " > 0"; break; + case ::MIR::eBinOp::GE: m_of << " >= 0"; break; + case ::MIR::eBinOp::LT: m_of << " < 0"; break; + case ::MIR::eBinOp::LE: m_of << " <= 0"; break; + default: + MIR_BUG(mir_res, "Unknown comparison of a &-ptr - " << e.src << " with " << ty); + } + m_of << ")"; + break; + } + emit_lvalue(ve.val_l); switch(ve.op) { |