diff --git a/fec/src/emitcm7.c b/fec/src/emitcm7.c index 7507d1d..27ca387 100644 --- a/fec/src/emitcm7.c +++ b/fec/src/emitcm7.c @@ -595,6 +595,28 @@ static void m7_emit_call(FeEmitter *e, FeNode *n) emit_expr(e,n->children->next); fputc(')',e->out); return; } + if (n->a && n->a->kind==FE_N_MEMBER && n->a->a && + n->a->a->kind==FE_N_IDENT && n->a->a->text && + strcmp(n->a->a->text,"mem")==0 && n->a->b && n->a->b->text && + strcmp(n->a->b->text,"create")==0 && n->children) { + FeType *created=n->children->sem_type; + FeType *owned=fe_type_owned(&e->check->types,created); + FeType *result=fe_type_error_union(&e->check->types,owned); + fputs(result->alloc_cname ? result->alloc_cname : "fe_bad_alloc",e->out); + fputc('(',e->out); emit_expr(e,n->children); fputc(')',e->out); + return; + } + if (n->a && n->a->kind==FE_N_MEMBER && n->a->a && + n->a->a->kind==FE_N_IDENT && n->a->a->text && + strcmp(n->a->a->text,"mem")==0 && n->a->b && n->a->b->text && + strcmp(n->a->b->text,"alloc_slice")==0 && n->children && + n->children->next) { + FeType *result=n->sem_type; + fputs(result && result->alloc_cname ? result->alloc_cname : + "fe_bad_slice_alloc",e->out); + fputc('(',e->out); emit_expr(e,n->children->next); fputc(')',e->out); + return; + } if (n->text && (strcmp(n->text,"@print")==0 || strcmp(n->text,"@fprint")==0 || strcmp(n->text,"@sprint")==0)) { emit_m4_builtin(e,n); diff --git a/fec/tests/m5/runtime.c b/fec/tests/m5/runtime.c index 43e51e0..5d3e6bb 100644 --- a/fec/tests/m5/runtime.c +++ b/fec/tests/m5/runtime.c @@ -7,7 +7,9 @@ extern void *malloc(size_t size); extern void free(void *p); -extern long fe_m5_runtime_run(long mode); +/* `run` returns !i32, which lowers to { error, value }. */ +struct fe_result_value_9 { unsigned short e; long v; }; +extern struct fe_result_value_9 fe_m5_runtime_run(long mode); extern unsigned short fe_m5_runtime_conditional(unsigned char flag); extern unsigned short fe_m5_runtime_argument_cleanup(void); extern unsigned short fe_m5_runtime_owned_slice(unsigned long n); @@ -64,9 +66,10 @@ void m5_free(void *p) int main(void) { - if (fe_m5_runtime_run(0) != 0) return 1; - if (fe_m5_runtime_run(1) != 9) return 2; - if (fe_m5_runtime_run(2) != 0) return 3; + struct fe_result_value_9 r; + r = fe_m5_runtime_run(0); if (r.e != 0 || r.v != 0) return 1; + r = fe_m5_runtime_run(1); if (r.e != 0 || r.v != 9) return 2; + r = fe_m5_runtime_run(2); if (r.e != 0 || r.v != 0) return 3; if (fe_m5_runtime_conditional(0) != 0) return 4; if (fe_m5_runtime_conditional(1) != 0) return 5; if (fe_m5_runtime_argument_cleanup() != 0) return 6; diff --git a/fec/tests/m5/runtime.fe b/fec/tests/m5/runtime.fe index 38a35da..b9dab0c 100644 --- a/fec/tests/m5/runtime.fe +++ b/fec/tests/m5/runtime.fe @@ -2,7 +2,7 @@ unit m5_runtime; fn take(p: ^i32) -> void { mem.destroy(p); } -pub fn run(mode: i32) -> i32 { +pub fn run(mode: i32) -> !i32 { var p: ^i32 = try mem.create(0); defer { mem.destroy(p); } p.^ = 7;