pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:3757:    } else {    fputc('0', stderr);    }    fprintf(stderr, ");\n");    indent++;    }   #endif       if ((a == b) || (!a)) {    ret = a; +  if (ret) add_ref(ret);    } else {    ret = BEGIN_CYCLIC(a, b);    if (!ret) {    SET_CYCLIC_RET(a);       ret = low_match_types2(a, b, flags); -  +  } else { +  add_ref(ret);    }    END_CYCLIC();    }      #ifdef PIKE_TYPE_DEBUG    if (l_flag>2) {    indent--;    fprintf(stderr, "%*s= ", indent*2, "");    if(ret)    simple_describe_type(ret);
pike.git/src/pike_types.cmod:3786:    }   #endif    return ret;   }      static struct pike_type *low_match_types2(struct pike_type *a,    struct pike_type *b,    int flags)   {    int correct_args; -  struct pike_type *ret; +  struct pike_type *ret = NULL; +  struct pike_type *tmp;      #ifdef PIKE_DEBUG    fatal_check_c_stack(1024);   #endif       switch(a->type & 0xff)    {    case T_AND:    ret = low_match_types(a->car, b, flags);    if(!ret) return 0; -  +  free_type(ret);    return low_match_types(a->cdr, b, flags);       case T_OR:    ret = low_match_types(a->car, b, flags);    if(ret && !(flags & NO_SHORTCUTS)) return ret;    if(ret)    { -  low_match_types(a->cdr, b, flags); +  struct pike_type *t = low_match_types(a->cdr, b, flags); +  if (t) { +  free_type(t); +  }    return ret;    }else{    return low_match_types(a->cdr, b, flags);    }       case PIKE_T_RING:    return low_match_types(a->car, b, flags);       case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    return low_match_types(a->cdr, b, flags);       case T_NOT: -  if(low_match_types(a->car, b, (flags ^ B_EXACT ) | NO_MAX_ARGS)) +  ret = low_match_types(a->car, b, (flags ^ B_EXACT ) | NO_MAX_ARGS); +  if (ret) { +  free_type(ret);    return 0; -  +  } +  add_ref(a);    return a;       case T_ASSIGN:    {    int m = CAR_TO_INT(a);    ret = low_match_types(a->cdr, b, flags);    if(ret && (!a_markers[m] || b->type != T_VOID))    { -  struct pike_type *tmp; -  +    #ifdef PIKE_DEBUG    if ((m < 0) || (m > 9)) {    Pike_fatal("marker out of range: %d\n", m);    }   #endif /* PIKE_DEBUG */       type_stack_mark();    push_finished_type_with_markers(b, b_markers, 0);    tmp = pop_unfinished_type();   
pike.git/src/pike_types.cmod:3869:    }    return ret;    }    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    {    int m = a->type - '0';    if(a_markers[m])    {    struct pike_type *t = a_markers[m]; -  struct pike_type *res; +    #ifdef PIKE_DEBUG    if(a_markers[m]->type == a->type)    Pike_fatal("Cyclic type!\n");    if(a_markers[m]->type == T_OR &&    a_markers[m]->car->type == a->type)    Pike_fatal("Cyclic type!\n");   #endif    a_markers[m] = NULL; -  res = low_match_types(t, b, flags); +  ret = low_match_types(t, b, flags);    if (a_markers[m]) { -  struct pike_type *tmp; +     a_markers[m] = or_pike_types(tmp = a_markers[m], t, 0);    free_type(tmp);    free_type(t);    } else {    a_markers[m] = t;    } -  return res; +  return ret;    } -  else +  else {    return low_match_types(mixed_type_string, b, flags);    } -  +  }       case PIKE_T_OPERATOR:    {    struct pike_type *t = a->car;    if ((t->type >= '0') && (t->type <= '9')) {    t = a_markers[t->type - '0'];    if (!t) t = zero_type_string;    }    t = apply_type_operator(a->type, t, a->cdr);    ret = low_match_types(t, b, flags);    free_type(t);    return ret;    }       case PIKE_T_TRANSITIVE:    {    /* FIXME */ -  +  add_ref(a);    return a;    }    }       switch(b->type & 0xff)    {    case T_AND:    ret = low_match_types(a, b->car, flags);    if(!ret) return 0; -  +  free_type(ret);    return low_match_types(a, b->cdr, flags);       case T_OR:    ret = low_match_types(a, b->car, flags);    if(ret && !(flags & NO_SHORTCUTS)) return ret;    if(ret)    { -  low_match_types(a, b->cdr, flags); +  struct pike_type *t = low_match_types(a, b->cdr, flags); +  if (t) { +  free_type(t); +  }    return ret;    }else{    return low_match_types(a, b->cdr, flags);    }       case PIKE_T_RING:    return low_match_types(a, b->car, flags);       case PIKE_T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    return low_match_types(a, b->cdr, flags);       case T_NOT: -  if(low_match_types(a, b->car, (flags ^ A_EXACT ) | NO_MAX_ARGS)) +  ret = low_match_types(a, b->car, (flags ^ A_EXACT ) | NO_MAX_ARGS); +  if (ret) { +  free_type(ret);    return 0; -  +  } +  add_ref(a);    return a;       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 *tmp; -  +     type_stack_mark();    push_finished_type_with_markers(a, a_markers, 0);    tmp=pop_unfinished_type();       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
pike.git/src/pike_types.cmod:3983:    }    return ret;    }    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':    {    int m = b->type - '0';    if(b_markers[m])    {    struct pike_type *t = b_markers[m]; -  struct pike_type *res; +    #ifdef PIKE_DEBUG    if(b_markers[m]->type == b->type)    Pike_fatal("Cyclic type!\n");   #endif    b_markers[m] = NULL; -  res = low_match_types(a, t, flags); +  ret = low_match_types(a, t, flags);    if (b_markers[m]) { -  struct pike_type *tmp; +     b_markers[m] = or_pike_types(tmp = b_markers[m], t, 0);    free_type(tmp);    free_type(t);    } else {    b_markers[m] = t;    } -  return res; +  return ret;    } -  else +  else {    return low_match_types(a, mixed_type_string, flags);    } -  +  }       case PIKE_T_OPERATOR:    {    struct pike_type *t = b->car;    if ((t->type >= '0') && (t->type <= '9')) {    t = b_markers[t->type - '0'];    if (!t) t = zero_type_string;    }    t = apply_type_operator(b->type, t, b->cdr);    ret = low_match_types(a, t, flags);    free_type(t);    return ret;    }       case PIKE_T_TRANSITIVE:    {    /* FIXME */ -  +  add_ref(a);    return a;    }    }       /* 'mixed' matches anything */       if((a->type == T_ZERO || a->type == T_MIXED) &&    !(flags & (A_EXACT|B_EXACT)) &&    (b->type != T_VOID))    {   #if 1 -  +  ret = NULL;    switch(b->type)    {    /* These types can contain sub-types */    case T_ARRAY: -  low_match_types(array_type_string, b, flags); +  ret = low_match_types(array_type_string, b, flags);    break;    case T_MAPPING: -  low_match_types(mapping_type_string, b, flags); +  ret = low_match_types(mapping_type_string, b, flags);    break;    case T_FUNCTION:    case T_MANY: -  low_match_types(function_type_string, b, flags); +  ret = low_match_types(function_type_string, b, flags);    break;    case T_MULTISET: -  low_match_types(multiset_type_string, b, flags); +  ret = low_match_types(multiset_type_string, b, flags);    break;    } -  +  if (ret) free_type(ret);   #endif -  +  add_ref(a);    return a;    }       if((b->type == T_ZERO || b->type == T_MIXED) &&    !(flags & (A_EXACT|B_EXACT)) &&    (a->type != T_VOID))    {   #if 1 -  +  ret = NULL;    switch(a->type)    {    /* These types can contain sub-types */    case T_ARRAY: -  low_match_types(a, array_type_string, flags); +  ret = low_match_types(a, array_type_string, flags);    break;    case T_MAPPING: -  low_match_types(a, mapping_type_string, flags); +  ret = low_match_types(a, mapping_type_string, flags);    break;    case T_FUNCTION:    case T_MANY: -  low_match_types(a, function_type_string, flags); +  ret = low_match_types(a, function_type_string, flags);    break;    case T_MULTISET: -  low_match_types(a, multiset_type_string, flags); +  ret = low_match_types(a, multiset_type_string, flags);    break;    } -  +  if (ret) free_type(ret);   #endif -  +  add_ref(a);    return a;    }       /* Special cases (tm) */    switch(TWOT(a->type, b->type))    {    case TWOT(T_PROGRAM, T_FUNCTION):    case TWOT(T_FUNCTION, T_PROGRAM):    case TWOT(T_PROGRAM, T_MANY):    case TWOT(T_MANY, T_PROGRAM):    /* FIXME: Should look at the sub-type of the program    * to determine the prototype to use.    */ -  +  add_ref(a);    return a;       case TWOT(PIKE_T_TYPE, T_FUNCTION):    case TWOT(PIKE_T_TYPE, T_MANY):    /* Convert the type to a casting function. */    type_stack_mark();    push_finished_type(a->car);    push_type(T_VOID);    push_type(T_MANY);    push_type(T_MIXED);    push_type(T_FUNCTION);    ret = a;    a = pop_unfinished_type();    if (low_match_types(a, b, flags)) {    free_type(a); -  +  add_ref(ret);    return ret;    }    free_type(a);    return NULL;       case TWOT(T_FUNCTION, PIKE_T_TYPE):    case TWOT(T_MANY, PIKE_T_TYPE):    /* Convert the type to a casting function. */    type_stack_mark();    push_finished_type(b->car);
pike.git/src/pike_types.cmod:4130:    return ret;       case TWOT(PIKE_T_TYPE, T_PROGRAM):    case TWOT(T_PROGRAM, PIKE_T_TYPE):    return low_match_types(a->car, b->car, flags);       case TWOT(T_OBJECT, T_FUNCTION):    case TWOT(T_OBJECT, T_MANY):    {    struct pike_type *s; -  if((s = low_object_lfun_type(a, LFUN_CALL))) +  if((s = low_object_lfun_type(a, LFUN_CALL))) {    return low_match_types(s, b, flags); -  +  }    if (flags & B_EXACT) {    /* A function isn't an object */    return 0;    } -  +  add_ref(a);    return a;    }       case TWOT(T_FUNCTION, T_OBJECT):    case TWOT(T_MANY, T_OBJECT):    {    struct pike_type *s;    if((s=low_object_lfun_type(b, LFUN_CALL)))    return low_match_types(a, s, flags);    if (flags & A_EXACT) {    /* A function isn't an object */    return 0;    } -  +  add_ref(a);    return a;    }    case TWOT(T_INT, T_ZERO):    {    if ((CAR_TO_INT(a) > 0) || (CDR_TO_INT(a) < 0)) {    return 0;    } -  +  add_ref(a);    return a;    }    case TWOT(T_ZERO, T_INT):    {    if ((CAR_TO_INT(b) > 0) || (CDR_TO_INT(b) < 0)) {    return 0;    } -  +  add_ref(a);    return a;    }    case TWOT(T_FUNCTION, T_FUNCTION):    case TWOT(T_FUNCTION, T_MANY):    case TWOT(T_MANY, T_FUNCTION):    case TWOT(T_MANY, T_MANY):    ret = a;    correct_args=0;    while ((a->type == T_FUNCTION) || (b->type == T_FUNCTION))    {
pike.git/src/pike_types.cmod:4190:    {    a = a->cdr;    }       b_tmp = b->car;    if (b->type == T_FUNCTION)    {    b = b->cdr;    }    -  if(!low_match_types(a_tmp, b_tmp, -  (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) +  if(!(tmp = low_match_types(a_tmp, b_tmp, +  (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT)))) {    return 0; -  +  } +  free_type(tmp);    if(++correct_args > max_correct_args)    if(!(flags & NO_MAX_ARGS))    max_correct_args=correct_args;    }       if ((a->type != T_MANY) || (b->type != T_MANY)) {    /* Handle the generic case. */    return low_match_types(a, b, flags);    }       /* check the 'many' type */    if(b->car->type != T_VOID &&    a->car->type != T_VOID)    { -  if(!low_match_types(a->car, b->car, -  (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT))) +  if(!(tmp = low_match_types(a->car, b->car, +  (flags | NO_MAX_ARGS) & ~(A_EXACT|B_EXACT)))) {    return 0;    } -  +  free_type(tmp); +  }    if(!(flags & NO_MAX_ARGS))    max_correct_args=MAX_INT32;    /* check the returntype */    a = a->cdr;    b = b->cdr;    if ((b->type == T_VOID) && (a->type != T_VOID)) {    /* Promote b to a function returning zero. */ -  if (!low_match_types(a, zero_type_string, flags & ~(A_EXACT|B_EXACT))) +  if (!(tmp = low_match_types(a, zero_type_string, +  flags & ~(A_EXACT|B_EXACT)))) {    return 0; -  +  } +  free_type(tmp);    } else if ((a->type == T_VOID) && (b->type != T_VOID)) {    /* Promote a to a function returning zero. */ -  if(!low_match_types(zero_type_string, b, flags & ~(A_EXACT|B_EXACT))) +  if(!(tmp = low_match_types(zero_type_string, b, +  flags & ~(A_EXACT|B_EXACT)))) {    return 0; -  } else if(!low_match_types(a, b, flags & ~(A_EXACT|B_EXACT))) return 0; +  } +  free_type(tmp); +  } else { +  if(!(tmp = low_match_types(a, b, flags & ~(A_EXACT|B_EXACT)))) { +  return 0; +  } +  free_type(tmp); +  } +  add_ref(ret);    return ret;    }       if(a->type != b->type) return 0;       ret=a;    switch(a->type)    {    case T_MAPPING: -  if(!low_match_types(a->car, b->car, -  flags & ~(A_EXACT|B_EXACT))) return 0; -  if(!low_match_types(a->cdr, b->cdr, -  flags & ~(A_EXACT|B_EXACT))) return 0; +  if(!(tmp = low_match_types(a->car, b->car, +  flags & ~(A_EXACT|B_EXACT)))) { +  return 0; +  } +  free_type(tmp); +  if(!(tmp = low_match_types(a->cdr, b->cdr, +  flags & ~(A_EXACT|B_EXACT)))) { +  return 0; +  } +  free_type(tmp);    break;       case T_OBJECT:   #if 0    if(a->cdr || b->cdr)    {    fprintf(stderr,"Type match1: ");    stupid_describe_type(a,type_length(a));    fprintf(stderr,"Type match2: ");    stupid_describe_type(b,type_length(b));
pike.git/src/pike_types.cmod:4269:    */    {    struct program *ap,*bp;    ap = id_to_program(CDR_TO_INT(a));    bp = id_to_program(CDR_TO_INT(b));       if(!ap || !bp) break;       implements_mode = 0;    -  if (!is_compatible(implements_a=ap,implements_b=bp)) +  if (!is_compatible(implements_a=ap,implements_b=bp)) {    return 0;    } -  +  }    break;       case T_INT:    {    INT32 amin = CAR_TO_INT(a);    INT32 amax = CDR_TO_INT(a);       INT32 bmin = CAR_TO_INT(b);    INT32 bmax = CDR_TO_INT(b);       if(amin > bmax || bmin > amax) return 0;    break;    }       case T_ARRAY:    case T_STRING: -  if(!low_match_types(a->cdr, b->cdr, -  flags & ~(A_EXACT|B_EXACT))) return 0; +  if(!(tmp = low_match_types(a->cdr, b->cdr, +  flags & ~(A_EXACT|B_EXACT)))) { +  return 0; +  } +  free_type(tmp);    /* FALLTHRU */       case T_PROGRAM:    case T_TYPE:    case T_MULTISET: -  if(!low_match_types(a->car, b->car, -  flags & ~(A_EXACT|B_EXACT))) return 0; +  if(!(tmp = low_match_types(a->car, b->car, +  flags & ~(A_EXACT|B_EXACT)))) { +  return 0; +  } +  free_type(tmp);    break;       case T_FLOAT:    case T_ZERO:    case T_VOID:    case T_MIXED:    break;   #ifdef PIKE_DEBUG    default:    Pike_fatal("Error in type string.\n");   #endif    } -  +  +  if (ret) add_ref(ret);    return ret;   }      /*    * Check the partial ordering relation.    *    * mixed    *    * int float string program function object    *
pike.git/src/pike_types.cmod:5214:   {    return low_pike_types_le(to, from, 0, LE_WEAK_OBJECTS);   }      /*    * Return the return type from a function call.    */   static int low_get_return_type(struct pike_type *a, struct pike_type *b)   {    struct compilation *c = THIS_COMPILATION; +  struct pike_type *t;    int tmp;    CHECK_COMPILER();    switch(a->type & 0xff)    {    case T_OR:    {    struct pike_type *o1, *o2;    o1=o2=0;       type_stack_mark();
pike.git/src/pike_types.cmod:5281:       case PIKE_T_OPERATOR:    {    struct pike_type *t = apply_type_operator(a->type, a->car, a->cdr);    tmp = low_get_return_type(t, b);    free_type(t);    return tmp;    }    }    -  a = low_match_types(a, b, NO_SHORTCUTS); -  if(a) +  t = low_match_types(a, b, NO_SHORTCUTS); +  if(t)    { -  +  a = t;   #if 0    if ((c->lex.pragmas & ID_STRICT_TYPES) &&    !low_pike_types_le(a, b, 0, 0)) {    yyreport_type(REPORT_WARNING, NULL, 0, b, NULL, 0, a, 0, "Type mismatch");    }   #endif /* 0 */    switch(a->type & 0xff)    {    case PIKE_T_TRANSITIVE:    a = a->car;    if (a->type != T_FUNCTION) {    if (a->type == T_MANY) {    a = a->cdr;    push_finished_type_with_markers(a, a_markers, 0); -  +  free_type(t);    return 1;    } -  return low_get_return_type(a, mixed_type_string); +  tmp = low_get_return_type(a, mixed_type_string); +  free_type(t); +  return tmp;    }    /* FALLTHRU */    case T_FUNCTION:    a = a->cdr;    while(a->type == T_FUNCTION) {    a = a->cdr;    }    if (a->type != T_MANY) { -  return low_get_return_type(a, mixed_type_string); +  tmp = low_get_return_type(a, mixed_type_string); +  free_type(t); +  return tmp;    }    /* FALLTHRU */    case T_MANY:    a = a->cdr;    push_finished_type_with_markers(a, a_markers, 0); -  +  free_type(t);    return 1;       case T_TYPE:    case T_PROGRAM:    push_finished_type(a->car); -  +  free_type(t);    return 1;       default:    push_type(T_MIXED); -  +  free_type(t);    return 1;    } -  +  free_type(t);    }    return 0;   }         int match_types(struct pike_type *a, struct pike_type *b)   {    clear_markers(); -  return !!low_match_types(a, b, 0); +  a = low_match_types(a, b, 0); +  free_type(a); +  return !!a;   }      int pike_types_le(struct pike_type *a,struct pike_type *b)   {    clear_markers();    return low_pike_types_le(a, b, 0, 0);   }      int check_variant_overload(struct pike_type *a, struct pike_type *b)   {
pike.git/src/pike_types.cmod:6142:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    case T_ASSIGN:    case T_SCOPE:    return low_minimum_arguments(q->cdr);       case T_FUNCTION:    num = 0;    while(q->type == T_FUNCTION)    { -  if(low_match_types(void_type_string, q->car, B_EXACT)) +  struct pike_type *t; +  if ((t = low_match_types(void_type_string, q->car, B_EXACT))) { +  free_type(t);    return num; -  +  }       num++;    q = q->cdr;    }    return num;    case T_MANY:    return 0;    }   }   
pike.git/src/pike_types.cmod:7465:    if (l_flag>2) {    fprintf(stderr, "%*sChecking argument type ", indent*2+2, "");    simple_describe_type(arg_type);    fprintf(stderr, " against function type ");    simple_describe_type(fun_type);    fprintf(stderr, ".\n");    }   #endif /* PIKE_DEBUG */    /* No need to perform advanced checking in the trivial case... */    if (arg_type != (tmp2 = fun_type->car)) { +  struct pike_type *t = NULL;    if (!((flags & CALL_INVERTED_TYPES)?    low_pike_types_le(tmp2, arg_type, 0,    LE_A_B_SWAPPED|LE_EXPLICIT_ZERO):    low_pike_types_le(arg_type, tmp2, 0, 0)) &&    ((flags & CALL_STRICT) || -  !low_match_types(arg_type, tmp2, NO_SHORTCUTS))) { +  !(t = low_match_types(arg_type, tmp2, NO_SHORTCUTS)))) {    /* No match. */   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "%*sNo match.\n", indent*2+2, "");    }   #endif /* PIKE_DEBUG */    res = NULL;    if (tmp) free_type(tmp);    break;    } -  +  if (t) free_type(t);    }    /* Match. */    if (fun_type->type == PIKE_T_FUNCTION) { -  +  struct pike_type *t = NULL;    /* Advance to the next argument. */    fun_type = fun_type->cdr;   #if 0    /* This test is too strict, and causes the type checker    * to complain about the last argument (even if correct)    * when there are too few arguments to the function.    */    if (!(flags & CALL_NOT_LAST_ARG) &&    (fun_type->type == PIKE_T_FUNCTION) && -  !low_match_types(fun_type->car, void_type_string, 0)) { +  !(t = low_match_types(fun_type->car, void_type_string, 0))) {    /* There are more required arguments. */   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "%*sMore arguments required.\n", indent*2+2, "");    }   #endif /* PIKE_DEBUG */    res = NULL;    if (tmp) free_type(tmp);    break;    } -  +  if (t) free_type(t);   #endif /* 0 */    }    type_stack_mark();    push_finished_type_with_markers(fun_type, b_markers, 0);    res = pop_unfinished_type();    if (tmp) free_type(tmp);       if ((Pike_compiler->compiler_pass == COMPILER_PASS_LAST) && sval) {    while (tmp2->type == PIKE_T_NAME) {    tmp2 = tmp2->cdr;