/*
- * Copyright (C) 2012
+ * Copyright (C) 2012, 2013
* Wolfgang Bumiller
* Dale Weiler
*
bool ast_compare_type(ast_expression *a, ast_expression *b)
{
+ if (a->expression.vtype == TYPE_NIL ||
+ b->expression.vtype == TYPE_NIL)
+ return true;
if (a->expression.vtype != b->expression.vtype)
return false;
if (!a->expression.next != !b->expression.next)
ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
{
+ ast_expression *exprtype = ontrue;
ast_instantiate(ast_ternary, ctx, ast_ternary_delete);
/* This time NEITHER must be NULL */
if (!ontrue || !onfalse) {
ast_propagate_effects(self, ontrue);
ast_propagate_effects(self, onfalse);
- if (!ast_type_adopt(self, ontrue)) {
+ if (ontrue->expression.vtype == TYPE_NIL)
+ exprtype = onfalse;
+ if (!ast_type_adopt(self, exprtype)) {
ast_ternary_delete(self);
return NULL;
}
count = vec_size(func->expression.params);
for (i = 0; i < count; ++i) {
- if (self->params[i]->expression.vtype != TYPE_NIL &&
- !ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i])))
+ if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i])))
{
char texp[1024];
char tgot[1024];
}
self->expression.outr = *out;
+ codegen_output_type(self, *out);
return true;
}
if (!*out)
return false;
self->expression.outr = *out;
+ codegen_output_type(self, *out);
return true;
}
/* Here, now, we need a PHI node
* but first some sanity checking...
*/
- if (trueval->vtype != falseval->vtype) {
+ if (trueval->vtype != falseval->vtype && trueval->vtype != TYPE_NIL && falseval->vtype != TYPE_NIL) {
/* error("ternary with different types on the two sides"); */
+ compile_error(ast_ctx(self), "internal error: ternary operand types invalid");
return false;
}
/* create PHI */
- phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), trueval->vtype);
- if (!phi)
+ phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->expression.vtype);
+ if (!phi) {
+ compile_error(ast_ctx(self), "internal error: failed to generate phi node");
return false;
+ }
ir_phi_add(phi, ontrue_out, trueval);
ir_phi_add(phi, onfalse_out, falseval);