Branch: Tag:

2021-03-01

2021-03-01 14:42:34 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler [Typechecker]: Second go at fixing some warnings.

las.cmod:fix_type_field() is called by optimize() from the leaves
going up. This means that the expression in eg `?` has typically
already been typechecked when it is received by fix_type_field().
Move the special case to mknode().

CAVEAT EMPTOR:
Calling fix_type_field() from mknode() in early compiler passes
may cause strange and unexpected failures. The special case type
adjustment is therefore only performed in the last compiler pass.

Fixes warnings from eg Getopt.

1029:    res->node_info |= OPT_NOT_CONST|OPT_SIDE_EFFECT;    break;    +  case '?': +  if (b && (b->token == ':') && CDR(b)) { +  /* There's an else statement. */ +  goto set_default_tree_info; +  } +  /* FALLTHRU */ +  case F_FOR: +  case F_LAND: +  if (Pike_compiler->compiler_pass == COMPILER_PASS_LAST) { +  if (a && (a->token == F_INITIALIZE)) { +  /* Special case to handle code like: +  * +  * if (string foo = expr) { xxx; } +  * while (string foo = expr) { xxx; } +  * for (;string foo = expr;yyy) { xxx; } +  * (string foo = expr) && xxx; +  * +  * where foo never will be zero even though expr may +  * very well be zero. +  */ +  fix_type_field(CDR(a)); +  if (CDR(a)->type && (CDR(a)->type != mixed_type_string)) { +  struct pike_type *not_zero = +  type_binop(PT_BINOP_MINUS, CDR(a)->type, zero_type_string, 0, 0, 0); +  if (not_zero && (not_zero != CDR(a)->type)) { +  free_type(CDR(a)->type); +  _CDR(a)->type = not_zero; +  } else { +  free_type(not_zero); +  } +  } +  } +  } +  goto set_default_tree_info; +     default: -  +  set_default_tree_info:    if(a) res->tree_info |= a->tree_info;    if(b) res->tree_info |= b->tree_info;    }
3541:    n->type = 0;    n->node_info &= ~OPT_TYPE_NOT_FIXED;    -  /* Special cases */ -  switch(n->token) { -  case '?': -  if (CDR(n) && (CDR(n)->token == ':') && CDDR(n)) { -  /* There's an else statement. */ -  break; -  } -  /* FALLTHRU */ -  case F_FOR: -  case F_LAND: -  /* Special case to handle code like: -  * -  * if (string foo = expr) { xxx } -  * -  * where foo never will be zero even though expr may -  * very well be zero. -  */ -  if (CAR(n) && (CAR(n)->token == F_INITIALIZE)) { -  fix_type_field(CDAR(n)); -  if (CDAR(n)->type && (CDAR(n)->type != mixed_type_string)) { -  struct pike_type *not_zero = -  type_binop(PT_BINOP_MINUS, CDAR(n)->type, zero_type_string, 0, 0, 0); -  if (not_zero && (not_zero != CDAR(n)->type)) { -  free_type(CDAR(n)->type); -  CDAR(n)->type = not_zero; -  } else { -  free_type(not_zero); -  } -  } -  } -  break; -  default: -  /* Make the C compiler happy. */ -  break; -  } -  +     /*    These two are needed if we want to extract types    from nodes while building the tree.