Branch: Tag:

2021-05-20

2021-05-20 10:06:15 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler [Typechecker]: Fix some issues with binop's on __unknown__.

Fixes some erroneous warnings.

4476:    break;    }    -  if (!a || !b) { -  if (a) { -  if (op & PT_BINOP_MINUS) { -  add_ref(a); -  return a; -  } -  } else if (b) { -  if (op & PT_BINOP_INVERSE_MINUS) { -  add_ref(b); -  return b; -  } -  } else if (op & PT_BINOP_NOR) { -  type_stack_mark(); -  push_type(T_MIXED); -  push_type(T_VOID); -  push_type(T_OR); -  return pop_unfinished_type(); -  } -  return NULL; -  } -  +     full_loop:    if (a == b) {    if (op & PT_BINOP_AND) {
4509:    }       /* First check for markers. */ -  switch(a->type) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker = alloc_remap_marker(remap, CAR_TO_INT(a), remap_flags);
4525:    return NULL;    }    } -  switch(b->type) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    {    int marker = alloc_remap_marker(remap, CAR_TO_INT(b),
4546:    }       /* Attributes and names. */ -  switch(a->type) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    case PIKE_T_NAME:    tmp = low_type_binop(op, a->cdr, b, remap, aflags, bflags, remap_flags);    if (!tmp) return NULL;
4574:    free_type(tmp);    return pop_unfinished_type();    } -  switch(b->type) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case PIKE_T_NAME:    tmp = low_type_binop(op, a, b->cdr, remap, aflags, bflags, remap_flags);    if (!tmp) return NULL;
4608:    }       /* Check consolidated types. */ -  switch(a->type) { +  switch(a?a->type:PIKE_T_UNKNOWN) {    case T_OR:    /* (a1 | a2) op b <==> (a1 op b) | (a2 op b) */    tmp = low_type_binop(op, a->car, b, remap, aflags, bflags, remap_flags);
4680:    return low_type_binop(op, a->car, b,    remap, aflags, bflags, remap_flags);    } -  switch(b->type) { +  switch(b?b->type:PIKE_T_UNKNOWN) {    case T_OR:    if ((op == PT_BINOP_MINUS) || (op == PT_BINOP_OR)) {    /* Special case to avoid excessively complicated expressions
4782:    remap, aflags, bflags, remap_flags);    }    +  /* +  * NB: At this point a and b are either NULL or a basic type. +  */ +  +  /* Handle a or b being NULL. */ +  /* NB: We know that a != b due to an earlier test. */ +  if (!a) { +  if (op & PT_BINOP_INVERSE_MINUS) { +  if (!((b == void_type_string) && (aflags & PT_FLAG_CMP_VOIDABLE)) && +  !((b == zero_type_string) && (aflags & PT_FLAG_CMP_NULLABLE))) { +  add_ref(b); +  return b; +  } +  } +  return NULL; +  } +  if (!b) { +  if (op & PT_BINOP_MINUS) { +  if (!((a == void_type_string) && (bflags & PT_FLAG_CMP_VOIDABLE)) && +  !((a == zero_type_string) && (bflags & PT_FLAG_CMP_NULLABLE))) { +  add_ref(a); +  return a; +  } +  } +  return NULL; +  } +     /* Check implicit casting. */    loop:    switch(TWOT(a->type & PIKE_T_MASK, b->type & PIKE_T_MASK)) {