pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:537:    * t->car 1404863f8 (1404863f8) 140557560 (1404863f8)    * t->cdr 1404b43d8 (1404b43d8) 400000000 (1404b43d8)    * t->next 0 100000000    * /grubba 2005-06-03    */    extra_debug_index = index;    }   #endif /* PIKE_EXTRA_DEBUG */    if (type == PIKE_T_UNKNOWN) return NULL;    for(t = pike_type_hash[index]; t; t = t->next) { -  /* if (type == PIKE_T_AUTO) break; */ +    #ifdef PIKE_EXTRA_DEBUG    if (index == extra_debug_index) {    fprintf(stderr,    " %s:%d:PIKE_EXTRA_DEBUG:\n"    " t: %p\n",    __FILE__, __LINE__,    t);    fprintf(stderr,    " t->type:%d (%s)\n"    " t->car: %p (%p)\n"
pike.git/src/pike_types.cmod:807:    }       TYPE_STACK_DEBUG("type_stack_pop_to_mark");   }      struct pike_type *debug_peek_type_stack(void)   {    return *(Pike_compiler->type_stackp);   }    - static void swap_type_stack(void) - { -  struct pike_type *tmp = Pike_compiler->type_stackp[-1]; -  Pike_compiler->type_stackp[-1] = Pike_compiler->type_stackp[0]; -  Pike_compiler->type_stackp[0] = tmp; - } -  +    void debug_push_int_type(INT_TYPE min, INT_TYPE max)   {   #if SIZEOF_INT_TYPE > 4   /* a bit kludgy: should maybe really allow 64 bit INT_TYPE */   /* see also extract_type_int */    if (min<MIN_INT32) min=MIN_INT32;    else if (min>MAX_INT32) min=MAX_INT32;    if (max<MIN_INT32) max=MIN_INT32;    else if (max>MAX_INT32) max=MAX_INT32;   #endif
pike.git/src/pike_types.cmod:960:   }      static struct pike_type *apply_type_operator(enum PIKE_TYPE op,    struct pike_type *arg1,    struct pike_type *arg2);      void debug_push_type_operator(enum PIKE_TYPE op, struct pike_type *arg)   {    struct pike_type *t = *Pike_compiler->type_stackp;    struct pike_type *tmp; +  int free_arg = 0;      #ifdef PIKE_DEBUG    if ((op & PIKE_T_MASK) != 0x80) {    Pike_fatal("Invalid operator for push_operator: 0x%04x\n", op);    }   #endif       /* Attempt to propagate the operator towards the leaf nodes. */    switch(t?(t->type & PIKE_T_MASK):PIKE_T_UNKNOWN) {    case '0': case '1': case '2': case '3': case '4':
pike.git/src/pike_types.cmod:1077:    switch(type & PIKE_T_MASK) {    case T_OR:    case T_AND:    /* Special case: Check if the two top elements are equal. */    if (Pike_compiler->type_stackp[-1] == Pike_compiler->type_stackp[0]) {    free_type(*(Pike_compiler->type_stackp--));    return;    }    /* Make a new type of the top two types. */    --Pike_compiler->type_stackp; - #if 0 +    #ifdef PIKE_DEBUG    if ((*Pike_compiler->type_stackp)->type == type) {    Pike_fatal("Invalid CAR to push_reverse_joiner_type().\n");    }   #endif /* PIKE_DEBUG */ - #endif +     *Pike_compiler->type_stackp = mk_type(type,    *Pike_compiler->type_stackp,    *(Pike_compiler->type_stackp+1),    ((type == T_OR)? PT_COPY_MORE : 0) |    PT_COPY_BOTH);    break;    default:    Pike_fatal("Illegal reverse joiner type: %d\n", type);    }   }   #define push_reverse_joiner_type(T) do { \    push_reverse_joiner_type(T); \    debug_malloc_touch(debug_peek_type_stack()); \    } while (0)      static void low_or_pike_types(struct pike_type *t1,    struct pike_type *t2,    int zero_implied);    - /* NB: Steals the references to cont and trans. */ - static struct pike_type *mk_transitive_type(struct pike_type *cont, -  struct pike_type *trans) - { -  struct pike_type *tmp, *tmp2, *ret; -  switch(cont->type) -  { -  case T_OR: case T_AND: -  add_ref(cont->car); -  add_ref(trans); -  tmp = mk_transitive_type(cont->car, trans); -  add_ref(cont->cdr); -  tmp2 = mk_transitive_type(cont->cdr, trans); -  ret = mk_type(cont->type, tmp, tmp2, PT_COPY_BOTH); -  free_type(cont); -  break; -  default: -  ret = mk_type(PIKE_T_TRANSITIVE, cont, trans, PT_COPY_BOTH); -  break; -  } -  return ret; - } -  +    void debug_push_type(unsigned int type)   {    /* fprintf(stderr, "push_type(%d)\n", type); */       switch(type & PIKE_T_MASK) {    case T_OR:    case T_AND:    /* Special case: Check if the two top elements are equal. */    if (Pike_compiler->type_stackp[-1] == Pike_compiler->type_stackp[0]) {    free_type(*(Pike_compiler->type_stackp--));
pike.git/src/pike_types.cmod:1236:    free_type(Pike_compiler->type_stackp[-1]);    Pike_compiler->type_stackp[-1] = NULL;    }    }    /* FALLTHRU */    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case PIKE_T_RING: +  case PIKE_T_TRANSITIVE:    /* Make a new type of the top two types. */    --Pike_compiler->type_stackp;    *Pike_compiler->type_stackp = mk_type(type,    *(Pike_compiler->type_stackp+1),    *Pike_compiler->type_stackp,    PT_COPY_BOTH);    break;    -  case PIKE_T_TRANSITIVE: -  /* Make a new type of the top two types. */ -  --Pike_compiler->type_stackp; -  *Pike_compiler->type_stackp = -  mk_transitive_type(*(Pike_compiler->type_stackp+1), -  *Pike_compiler->type_stackp); -  break; -  +     case T_PROGRAM:    if (!*Pike_compiler->type_stackp ||    (*Pike_compiler->type_stackp)->type != T_OBJECT) {    struct pike_type *t = (*Pike_compiler->type_stackp);    while (t && ((t->type == PIKE_T_NAME) || (t->type == PIKE_T_ATTRIBUTE))) {    t = t->cdr;    }    if (!t || (t->type != T_OBJECT)) {    /* Not a program type, convert it to a type type. */    type = T_TYPE;
pike.git/src/pike_types.cmod:1599:    if (markers[m]) push_type(T_OR);    } else if (!markers[m]) {    push_type(PIKE_T_UNKNOWN);    }    TYPE_STACK_DEBUG("push_finished_type_with_markers");    return;    } else if (type->type == T_ASSIGN) {    /* Assign. */    int marker = PTR_TO_INT(type->car);   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (marker >= 7)) { +  if (l_flag > 2) {    fprintf(stderr, "Assign to marker $%"PRINTPTRDIFFT"d.\n",    CAR_TO_INT(type));    }   #endif /* PIKE_TYPE_DEBUG */    if (marker_set & (PT_FLAG_ASSIGN_0 << marker)) {    /* The assignment should be kept as-is. */   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (marker >= 7)) { +  if (l_flag > 2) {    fprintf(stderr, "Keep assignment.\n");    }   #endif /* PIKE_TYPE_DEBUG */    /* Clear the flag. */    push_finished_type_with_markers(type->cdr, markers,    marker_set &    ~(PT_FLAG_ASSIGN_0 << marker));    push_assign_type('0' + marker);    TYPE_STACK_DEBUG("push_finished_type_with_markers");    return;    } else {   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (marker >= 7)) { +  if (l_flag > 2) {    fprintf(stderr, "Strip assignment.\n");    }   #endif /* PIKE_TYPE_DEBUG */    type = type->cdr;    goto recurse;    }    } else if (type->type == PIKE_T_NAME) {    /* Strip the name, since it won't be correct anymore. */    type = type->cdr;    goto recurse;
pike.git/src/pike_types.cmod:2359:    ++*s;    internal_parse_typeC(s);    push_type(T_OR);    }   }      /* This function is used when adding simul efuns so that    * the types for the functions can be easily stored in strings.    * It takes a string on the exact same format as Pike and returns a type    * struct. -  * -  * NB: Used by the efun __parse_pike_type(), which in turn is -  * used by build_pgtk.pike. +     */   struct pike_type *parse_type(const char *s)   {    struct pike_type *ret;   #ifdef PIKE_DEBUG    struct pike_type **ts=Pike_compiler->type_stackp;    struct pike_type ***ptms=Pike_compiler->pike_type_mark_stackp;   #endif       /* fprintf(stderr, "parse_type(\"%s\")...\n", s); */
pike.git/src/pike_types.cmod:2401:      void simple_describe_type(struct pike_type *s)   {    DECLARE_CYCLIC();    if (BEGIN_CYCLIC(s, NULL)) {    Pike_fatal("Circular type!\n");    }    SET_CYCLIC_RET(1);       if (s) { - #ifdef PIKE_DEBUG -  if (l_flag > 10) { -  fprintf(stderr, "[[[%p:%ld]]]", s, (long)s->refs); -  } - #endif +  /* fprintf(stderr, "[[[%p]]]", s); */    switch(s->type & PIKE_T_MASK) {    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    fprintf(stderr, "$%d", s->type-'0');    break;       case PIKE_T_NAME:    fprintf(stderr, "{ %s = ", ((struct pike_string *)s->car)->str);    simple_describe_type(s->cdr);    fprintf(stderr, " }");
pike.git/src/pike_types.cmod:3255:    goto loop;    case T_MIXED:    t = int_type_string;    goto loop;    default:    break;    }    return ret;   }    + static void low_or_pike_types(struct pike_type *t1, +  struct pike_type *t2, +  int zero_implied); +    /* Push either t1, t2 or the OR of t1 and t2.    * Returns -1 if t1 was pushed.    * 0 if the OR was pushed. (Successful join)    * 1 if t2 was pushed.    *    * zero_implied: One of:    * 0 the zero type (if any) must be explicit in the result.    * 1 the zero type is implicit.    * 2 zero is explicit and integers are regarded as masks (cf enums).    * 3 zero is implicit and integers are regarded as masks (cf enums).    */   static int lower_or_pike_types(struct pike_type *t1,    struct pike_type *t2,    int zero_implied,    int elem_on_stack)   {    int ret = 0;    struct pike_type *t = NULL;    struct pike_type *top = NULL; -  struct pike_type *free_me = NULL; +    #if 0    fprintf(stderr, " lower_or_pike_types(");    simple_describe_type(t1);    fprintf(stderr, ", ");    simple_describe_type(t2);    fprintf(stderr, ")\n");   #endif    if (t1 == t2) {    t = t1;    } else if (!t1) {    t = t2;    ret = 1;    } else if (!t2) {    t = t1;    ret = -1;    } else if ((zero_implied & 1) && (t1->type == T_ZERO)) {    t = t2; -  if ((zero_implied & 2) && (t2->type == T_INT)) { -  if ((CAR_TO_INT(t2) <= 0) && (CDR_TO_INT(t2) >= 0)) { -  /* No need to do anything. */ -  } else { -  int min = CAR_TO_INT(t2); -  int max = CDR_TO_INT(t2); -  if (max < 0) max = 0; -  if (min > 0) min = 0; -  type_stack_mark(); -  push_int_type(min, max); -  free_me = t = pop_unfinished_type(); -  } -  } +     } else if ((zero_implied & 1) && (t2->type == T_ZERO)) {    t = t1; -  if ((zero_implied & 2) && (t1->type == T_INT)) { -  if ((CAR_TO_INT(t1) <= 0) && (CDR_TO_INT(t1) >= 0)) { -  /* No need to do anything. */ -  } else { -  int min = CAR_TO_INT(t1); -  int max = CDR_TO_INT(t1); -  if (max < 0) max = 0; -  if (min > 0) min = 0; -  type_stack_mark(); -  push_int_type(min, max); -  free_me = t = pop_unfinished_type(); -  } -  } +     } else if ((t1->type == T_NOT) && pike_types_le(t1->car, t2, 0, 0)) {    t = mixed_type_string;    } else if ((t2->type == T_NOT) && pike_types_le(t2->car, t1, 0, 0)) {    t = mixed_type_string;    } else if ((t1->type ^ '0') < (t2->type ^ '0')) {    /* Note: Adjusted order to get markers first. */    t = t1;    ret = -1;    } else if ((t1->type ^ '0') > (t2->type ^ '0')) {    /* Note: Adjusted order to get markers first. */
pike.git/src/pike_types.cmod:3558:    max1 |= max2;       if ((min1 < 0) && (min2 < 0)) {    min1 &= min2;    }    }       if ((max2 < MAX_INT32) && (min1 > max2 + 1)) {    /* No overlap. */    push_finished_type(t); + #ifdef PIKE_DEBUG    } else if ((max1 < MAX_INT32) && (min2 > max1 + 1)) {    /* No overlap and wrong order! */ -  push_finished_type(t); -  swap_type_stack(); +  Pike_fatal("Bad integer ordering in lower_or_pike_types().\n"); + #endif    } else {    Pike_compiler->type_stackp--;    free_type(top);    /* Overlap */    min1 = MINIMUM(min1, min2);    max1 = MAXIMUM(max1, max2);       push_int_type(min1, max1);    }    }
pike.git/src/pike_types.cmod:3627:    Pike_compiler->type_stackp--;    push_finished_type(t);    push_finished_type(top);    free_type(top);    } else {    push_finished_type(t);    }    break;    }    } -  free_type(free_me); +     return ret;   }      static void low_or_pike_types(struct pike_type *t1,    struct pike_type *t2,    int zero_implied)   {   #ifdef PIKE_DEBUG    struct pike_type *arg1 = t1;    struct pike_type *arg2 = t2;
pike.git/src/pike_types.cmod:5708:    return pop_unfinished_type();       case TWOT(T_FUNCTION, T_FUNCTION):    case TWOT(T_FUNCTION, T_MANY):    case TWOT(T_MANY, T_FUNCTION):    case TWOT(T_MANY, T_MANY):    {    int nargs;    struct pike_type *ai = a;    struct pike_type *bi = b; -  /* FIXME: Only use implicit nullable for legacy types. */ -  enum pt_cmp_flags avoidable = PT_FLAG_CMP_NULLABLE; -  enum pt_cmp_flags bvoidable = PT_FLAG_CMP_NULLABLE; +  enum pt_cmp_flags avoidable = 0; +  enum pt_cmp_flags bvoidable = 0;       if ((b->type == T_MANY) && !b->car &&    ((b->cdr == mixed_type_string) || (b->cdr == any_type_string))) {    /* Common case.    * function(__unknown__...:mixed) or function(__unknown__...:mixed|void)    */    if (op == PT_BINOP_AND) {    return remap_markers(a, remap, remap_flags);    }    return NULL;
pike.git/src/pike_types.cmod:5766:    * many(assign(m2, mixed), or(m1, m2))).    */    while(1) {    /* Invariant:    * ai->type and bi->type are either T_FUNCTION or T_MANY.    */       /* Check the argument. */       /* NB: The MANY argument is always voidable. */ -  if (ai->type == T_MANY) avoidable = PT_FLAG_CMP_VOIDABLE; -  if (bi->type == T_MANY) bvoidable = PT_FLAG_CMP_VOIDABLE; +  if (ai->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE; +  if (bi->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;      #if 0    fprintf(stderr, "arg_check(op: 0x%x, ", op);    simple_describe_type(ai);    fprintf(stderr, " (%d), ", avoidable);    simple_describe_type(bi);    fprintf(stderr, " (%d))\n\n", bvoidable);   #endif       /* FIXME: Use implicit nullable for legacy types? */
pike.git/src/pike_types.cmod:5792:    * due to the implicit ALL and EXIST operators    * for arguments in function types. Eg there are    * many more functions that accept 0 as an argument    * than there are functions that accept any integer.    * Thus function(int:mixed) is a stricter type    * than function(zero:mixed).    */    tmp = low_type_binop(PT_BINOP_OR, ai->car, bi->car, remap,    avoidable, bvoidable, remap_flags);    -  if (remap_flags & PT_FLAG_REMAP_TRACE) { -  fprintf(stderr, "tmp: "); -  simple_describe_type(tmp); -  fprintf(stderr, "\n"); -  } -  +     /* Advance to the next argument. */    if (ai->type == T_FUNCTION) {    ai = ai->cdr;    }    if (bi->type == T_FUNCTION) {    bi = bi->cdr;    }    if ((ai->type != T_FUNCTION) && (ai->type != T_MANY)) {    if (aret) {    Pike_fatal("Unsupported type operation.\n");
pike.git/src/pike_types.cmod:5882:    * B - A == Ø && X - Y == Z # Argument overlap    * ==> T_FUNCTION(A, Z) # (Recurse)    *    * B - A == B ==> T_FUNCTION(A, X) # No overlap    * # No need to recurse    *    * B - A == C && X - Y == Z # Partial overlap    * ==> T_FUNCTION(A - B, X) | # Keep and    * T_FUNCTION(A, Z) # Recurse    * +  * T_FUNCTION(A - B, X) | T_FUNCTION(A, X - Y) +  *    * T_MANY analogous with T_MANY substituted for T_FUNCTION above.    */       /* Check the argument. */       /* NB: The MANY argument is always voidable. */ -  if (ai->type == T_MANY) avoidable = PT_FLAG_CMP_VOIDABLE; -  if (bi->type == T_MANY) bvoidable = PT_FLAG_CMP_VOIDABLE; +  if (ai->type == T_MANY) avoidable |= PT_FLAG_CMP_VOIDABLE; +  if (bi->type == T_MANY) bvoidable |= PT_FLAG_CMP_VOIDABLE;      #if 0    fprintf(stderr, "arg_check(op: 0x%x, ", op);    simple_describe_type(ai);    fprintf(stderr, " (%d), ", avoidable);    simple_describe_type(bi);    fprintf(stderr, " (%d))\n\n", bvoidable);   #endif       if (!bi->car) {
pike.git/src/pike_types.cmod:6730:    */    return NULL;    }    }    break;    case PT_BINOP_MINUS:    if (!b->cdr) {    return NULL;    }    if (a->cdr) { -  if ((a->cdr == b->cdr) && (!b->car || a->car)) { +  if (a->cdr == b->cdr) {    return NULL;    }    if (a->car && b->car) {    /* This is only possible if a->cdr == b->cdr, but that is    * handled above.    */    add_ref(a);    return a;    }    {
pike.git/src/pike_types.cmod:6755:    return NULL;    }    if (!is_compatible(ap, bp)) {    add_ref(a);    return a;    }    }    }    break;    default: -  fprintf(stderr, "Unsupported operation for objects. Binop: 0x%02x\n", op); +     break;    }       type_stack_mark();    push_finished_type(b);    push_finished_type(a);    push_binop(op);    return pop_unfinished_type();    }   
pike.git/src/pike_types.cmod:8538:    if(ret && (!a_markers[m] || b->type != T_VOID))    {    struct pike_type *filtered_b = NULL;      #ifdef PIKE_DEBUG    if ((m < 0) || (m > 9)) {    Pike_fatal("marker out of range: $%d\n", m);    }   #endif /* PIKE_DEBUG */    -  if (a->cdr && b && (a->cdr->type == T_OBJECT) && -  (b->type == T_MAPPING)) { -  pike_gdb_breakpoint(0); -  } -  +     type_stack_mark();    push_finished_type_with_markers(b, b_markers, 0);    tmp = pop_unfinished_type();       filtered_b = type_binop(PT_BINOP_AND,    tmp, a->cdr,    PT_FLAG_CMP_NULLABLE,    PT_FLAG_CMP_NULLABLE,    PT_FLAG_REMAP_INHIBIT);    free_type(tmp);    tmp = filtered_b;       type_stack_mark();    low_or_pike_types(a_markers[m], tmp, 0);    if(a_markers[m]) free_type(a_markers[m]);    free_type(tmp);    a_markers[m] = pop_unfinished_type();      #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (m >= 7)) { +  if (l_flag>2) {    fprintf(stderr, "%*sa_markers[%d]=",    indent*2, "", m);    simple_describe_type(a_markers[m]);    fputc('\n', stderr);    }   #endif   #ifdef PIKE_DEBUG    if(a_markers[m] && (a_markers[m]->type == m+'0'))    Pike_fatal("Cyclic type!\n");   #endif
pike.git/src/pike_types.cmod:8699:    return low_match_types(a, any_type_string, flags);       case T_ASSIGN:    {    int m = CAR_TO_INT(b);    ret = low_match_types(a, b->cdr, flags);    if(ret && (!b_markers[m] || a->type != T_VOID))    {    struct pike_type *filtered_a = NULL;    -  if (b->cdr && a && (b->cdr->type == T_OBJECT) && -  (a->type == T_MAPPING)) { -  pike_gdb_breakpoint(0); -  } -  +     type_stack_mark();    push_finished_type_with_markers(a, a_markers, 0);    tmp=pop_unfinished_type();       filtered_a = type_binop(PT_BINOP_AND,    tmp, b->cdr,    PT_FLAG_CMP_NULLABLE,    PT_FLAG_CMP_NULLABLE,    PT_FLAG_REMAP_INHIBIT);    free_type(tmp);    tmp = filtered_a;       type_stack_mark();    low_or_pike_types(b_markers[m], tmp, 0);    if(b_markers[m]) free_type(b_markers[m]);    free_type(tmp);    b_markers[m] = pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (m >= 7)) { +  if (l_flag>2) {    fprintf(stderr, "%*sb_markers[%d]=",    indent*2, "", m);    simple_describe_type(b_markers[m]);    fputc('\n', stderr);    }   #endif   #ifdef PIKE_DEBUG    if(b_markers[m] && (b_markers[m]->type == m+'0'))    Pike_fatal("Cyclic type!\n");   #endif
pike.git/src/pike_types.cmod:9179:    * ie it's assumed that calling a function(mapping(string|int:string|int):void)    * with a mapping(int:int) won't change the type of the mapping after the    * operation.    */   static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,    int array_cnt, unsigned int flags);   static int low_pike_types_le(struct pike_type *a, struct pike_type *b,    int array_cnt, unsigned int flags)   {    int res; -  int save_l = l_flag; +     DECLARE_CYCLIC();    -  if (b && a && (b->type == T_MANY) && (a->type == PIKE_T_TRANSITIVE)) { -  l_flag = 3; -  } -  +    #ifdef PIKE_TYPE_DEBUG    if (l_flag>2) {   #if 0    struct compilation *c = MAYBE_THIS_COMPILATION;    if (c && c->lex.current_file)    fprintf (stderr, "%*s%s:%d:\n", indent * 2, "",    c->lex.current_file->str, c->lex.current_line);   #endif    fprintf(stderr, "%*slow_pike_types_le(", indent*2, "");    simple_describe_type(a);
pike.git/src/pike_types.cmod:9217:    res = low_pike_types_le2(a, b, array_cnt, flags);    }    END_CYCLIC();      #ifdef PIKE_TYPE_DEBUG    if (l_flag>2) {    indent--;       fprintf(stderr, "%*s= %d\n", indent*2, "", res);    } -  -  if (l_flag != save_l) { -  fprintf(stderr, "\n---------\n\n"); -  } +    #endif /* PIKE_TYPE_DEBUG */ -  -  l_flag = save_l; +     return res;   }      static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,    int array_cnt, unsigned int flags)   {    struct compilation *c = MAYBE_THIS_COMPILATION;    int ret;       recurse:
pike.git/src/pike_types.cmod:9363:   #endif    /* FIXME: This is wrong... */    return !low_pike_types_le(b->car, a, -array_cnt, flags);       case T_ASSIGN: {    struct pike_type **aa_markers = a_markers;    struct pike_type **bb_markers = b_markers;    int m = CAR_TO_INT(b);    ret = low_pike_types_le(a, b->cdr, array_cnt, flags);    -  if (b->cdr && a && (b->cdr->type == T_OBJECT) && -  (a->type == T_MAPPING)) { -  pike_gdb_breakpoint(0); -  } -  +     if (flags & LE_A_B_SWAPPED) {    aa_markers = b_markers;    bb_markers = a_markers;    }       if(ret && (!bb_markers[m] || a->type != T_VOID))    {    int m = CAR_TO_INT(b);    struct pike_type *tmp;    int i;
pike.git/src/pike_types.cmod:9391:    for(i = array_cnt; i < 0; i++)    push_unlimited_array_type(T_ARRAY);    tmp=pop_unfinished_type();       type_stack_mark();    low_or_pike_types(bb_markers[m], tmp, 0);    if(bb_markers[m]) free_type(bb_markers[m]);    free_type(tmp);    bb_markers[m] = pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (m >= 7)) { +  if (l_flag>2) {    if (flags & LE_A_B_SWAPPED) {    fprintf(stderr, "%*sa_markers[%c]=",    indent * 2, "", (char)(m+'0'));    simple_describe_type(a_markers[m]);    } else {    fprintf(stderr, "%*sb_markers[%c]=",    indent * 2, "", (char)(m+'0'));    simple_describe_type(b_markers[m]);    }    fprintf(stderr, "\n");
pike.git/src/pike_types.cmod:9609:   #endif    /* FIXME: This is wrong... */    return !low_pike_types_le(b, a->car, -array_cnt, flags);       case T_ASSIGN: {    struct pike_type **aa_markers = a_markers;    struct pike_type **bb_markers = b_markers;    int m = CAR_TO_INT(a);    ret = low_pike_types_le(a->cdr, b, array_cnt, flags);    -  if (a->cdr && b && (a->cdr->type == T_OBJECT) && -  (b->type == T_MAPPING)) { -  pike_gdb_breakpoint(0); -  } -  +     if (flags & LE_A_B_SWAPPED) {    aa_markers = b_markers;    bb_markers = a_markers;    }       if(ret && (!aa_markers[m] || (b->type != T_VOID)))    {    struct pike_type *tmp;    int i;   
pike.git/src/pike_types.cmod:9636:    for(i=array_cnt; i > 0; i--)    push_unlimited_array_type(T_ARRAY);    tmp=pop_unfinished_type();       type_stack_mark();    low_or_pike_types(aa_markers[m], tmp, 0);    if(aa_markers[m]) free_type(aa_markers[m]);    free_type(tmp);    aa_markers[m] = pop_unfinished_type();   #ifdef PIKE_TYPE_DEBUG -  if ((l_flag > 2) || (m >= 7)) { +  if (l_flag>2) {    if (flags & LE_A_B_SWAPPED) {    fprintf(stderr, "%*sb_markers[%c]=",    indent * 2, "", (char)(m+'0'));    simple_describe_type(b_markers[m]);    } else {    fprintf(stderr, "%*sa_markers[%c]=",    indent * 2, "", (char)(m+'0'));    simple_describe_type(a_markers[m]);    }    fprintf(stderr, "\n");
pike.git/src/pike_types.cmod:10862:    case T_MULTISET:    case T_MAPPING:    /* Illegal range operation. */    /* FIXME: Strict type warning. */    return 0;       case T_ARRAY: /* FIXME: cdr */    case T_STRING:    /* Check that the index types are compatible with int. */    { -  /* Validate index1 and index2 type against index type. */ -  INT_TYPE index_range[2] = { MAX_INT32, MIN_INT32 }; -  INT_TYPE index1_range[2] = { MAX_INT32, MIN_INT32 }; -  INT_TYPE index2_range[2] = { MAX_INT32, MIN_INT32 }; -  INT_TYPE result_range[2] = { 0, MIN_INT32 }; -  if (index1_type) { -  if (!get_int_type_range(index1_type, index1_range)) { +  /* FIXME: Validate index1 and index2 type against index type. */ +  if (index1_type && !match_types(int_type_string, index1_type)) {    ref_push_type_value(t);    yytype_report(REPORT_WARNING, NULL, 0, int_type_string,    NULL, 0, index1_type,    1, "Bad argument 1 to range operator on %O.");    /* Bad index1 type. */    return 0;    } -  } else { -  index1_range[1] = index1_range[0] = 0; -  } -  if (index2_type) { -  if (!get_int_type_range(index2_type, index2_range)) { +  if (index2_type && !match_types(int_type_string, index2_type)) {    ref_push_type_value(t);    yytype_report(REPORT_WARNING, NULL, 0, int_type_string,    NULL, 0, index2_type,    1, "Bad argument 2 to range operator on %O.");    /* Bad index2 type. */    return 0;    } -  } else { -  index2_range[0] = index2_range[1] = MAX_INT32; -  } -  if (t->car && !get_int_type_range(t->car, index_range)) { -  /* FIXME: Strange index range for t. */ -  } +     /* FIXME: Adjust index type of result to be from    * min(index1) to max(index2).    * FIXME: Do we need to check against the index type too?    */ -  /* The range is from max(0, min(index2, index) - max(index1)) to -  * min(max(index2, index) - max(0, min(index1))) -  */ -  if (index_range[1] < MAX_INT32) { -  if (index1_range[0] >= index_range[1]) { -  /* Result is always empty. */ -  result_range[1] = 0; -  } else { -  if (index2_range[0] > index_range[0]-1) { -  index2_range[0] = index_range[0]-1; +     } -  if (index2_range[1] > index_range[1]-1) { -  index2_range[1] = index_range[1]-1; -  } -  } -  } -  if (index2_range[1] < 0) { -  /* Result is always empty. */ -  result_range[1] = 0; -  } else { -  if (index2_range[1] >= MAX_INT32) { -  result_range[1] = index_range[1]; -  } -  result_range[1] = 1 + index2_range[1] - index1_range[0]; -  if (result_range[1] < 0) result_range[1] = 0; -  result_range[0] = 1 + index2_range[0] - index1_range[1]; -  if (result_range[0] < 0) result_range[0] = 0; -  } - #if 0 -  type_stack_mark(); -  if (result_range[1]) { -  push_finished_type(t->cdr); -  } else { -  push_type(PIKE_T_UNKNOWN); -  } -  push_int_type(result_range[0], result_range[1]); -  push_type(t->type); -  return pop_unfinished_type(); - #else -  fprintf(stderr, "%s(%ld..%ld)[int(%ld..%ld)..int(%ld..%ld)] ==> %s(%ld..%ld)\n", -  get_name_of_type(t->type), index_range[0], index_range[1], -  index1_range[0], index1_range[1], -  index2_range[0], index2_range[1], -  get_name_of_type(t->type), result_range[0], result_range[1]); - #endif -  } +     /* FALLTHROUGH */    default:    /* Identity. */    add_ref(t);    return t;       case T_OR:    {    struct pike_type *a,*b;    a = low_range_type(t->car, index1_type, index2_type);
pike.git/src/pike_types.cmod:10980:   struct pike_type *range_type(struct pike_type *type,    struct pike_type *index1_type,    struct pike_type *index2_type)   {    struct pike_type *t;    clear_markers();    t = low_range_type(type, index1_type, index2_type);    if(!t) {    yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL,    0, "Invalid range operation."); -  fprintf(stderr, "type: "); -  simple_describe_type(type); -  fprintf(stderr, "\nindex1: "); -  simple_describe_type(index1_type); -  fprintf(stderr, "\nindex2: "); -  simple_describe_type(index2_type); -  fprintf(stderr, "\n"); +     copy_pike_type(t, type);    }    return t;   }         static struct pike_type *low_array_value_type(struct pike_type *arr_t)   {    struct pike_type *res = NULL;    struct pike_type *sub_t;
pike.git/src/pike_types.cmod:11598:    *    * Flags:    * 1 SOFT_WEAKER Weaker type.    */   struct pike_type *soft_cast(struct pike_type *soft_type,    struct pike_type *orig_type,    int flags)   {    if (flags & SOFT_WEAKER) {    return type_binop(PT_BINOP_AND, orig_type, soft_type, -  PT_FLAG_CMP_NULLABLE, 0, PT_FLAG_REMAP_TRACE); +  PT_FLAG_CMP_NULLABLE, 0, 0);    } else {    return type_binop(PT_BINOP_AND, orig_type, soft_type, 0, 0, 0);    }   }      /**    * Check whether sval is a valid value for a variable of    * type type.    *    * Returns 1 if ok, and 0 (zero) otherwise.
pike.git/src/pike_types.cmod:12041:    simple_describe_type(arg_type);    fprintf(stderr, ", 0x%04x, %p(argno:%d), %p)...\n",    flags, cs, cs?cs->argno:-1, sval);    }   #endif /* PIKE_DEBUG */       loop:    /* Count the number of array levels. */    while(fun_type && (fun_type->type == PIKE_T_ARRAY)) {    array_cnt++; -  if (!fun_type->cdr) break; +     fun_type = fun_type->cdr;    }       switch(fun_type?(fun_type->type & PIKE_T_MASK):PIKE_T_UNKNOWN) {    case T_SCOPE:    /* FIXME: Save and restore the corresponding marker set. */    case T_ASSIGN:    case PIKE_T_NAME:    fun_type = fun_type->cdr;    goto loop;
pike.git/src/pike_types.cmod:12493:   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "%*sSuccess.\n", indent*2+2, "");    }   #endif /* PIKE_DEBUG */    break;    default:    /* Not a callable. */    break;    } -  +     /* CAVEAT EMPTOR: When flags & CALL_ARG_LVALUE the    * PT_FLAG_REMAP_SWAP_MARKERS flag in remap_flags    * may be inverted here if the code above has exited    * via a jump to no_match.    */    if (!array_cnt || !res) {   #ifdef PIKE_DEBUG    if (l_flag>2) {    if (res) {    fprintf(stderr, "%*s==> ", indent*2, "");    simple_describe_type(res);    } else {    fprintf(stderr, "%*s==> NULL", indent*2, "");    }    fprintf(stderr, "\n");    }   #endif /* PIKE_DEBUG */    return res;    }    -  if (array_cnt && res) { +     type_stack_mark();    push_finished_type(res);    free_type(res);    while(array_cnt--) {    push_unlimited_array_type(PIKE_T_ARRAY);    }    res = pop_unfinished_type(); -  } +       #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "%*s==> ", indent*2, "");    simple_describe_type(res);    fprintf(stderr, "\n");    }   #endif /* PIKE_DEBUG */       return res;