pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.c:6269:   #endif /* PIKE_DEBUG */    res = NULL;    if (tmp) free_type(tmp);    break;    }    }    /* Match. */    if (fun_type->type == PIKE_T_FUNCTION) {    /* 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)) {    /* 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;    } -  + #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 == 2) && sval) {    while (tmp2->type == PIKE_T_NAME) {    tmp2 = tmp2->cdr;    }
pike.git/src/pike_types.c:7002:    } else if (c->lex.pragmas & ID_STRICT_TYPES) {    yywarning("In argument %d to %S: The @-operator argument has a max length of %d.",    argno, fun_name, 256-cnt);    }    }       return res;   }      /* NOTE: fun_type loses a reference. */ - struct pike_type *new_check_call(struct pike_string *fun_name, + static struct pike_type *new_check_call_arg(struct pike_string *fun_name,    struct pike_type *fun_type, -  node *args, INT32 *argno, INT32 flags) +  node *args, INT32 *argno, +  INT32 flags)   {    struct compilation *c = THIS_COMPILATION;    struct pike_type *tmp = NULL;    struct pike_type *res = NULL;    struct svalue *sval = NULL;       CHECK_COMPILER();       debug_malloc_touch(fun_type);    -  while (args && -  ((args->token == F_ARG_LIST) || (args->token == F_LVALUE_LIST)) && -  fun_type) { -  if (args->token == F_LVALUE_LIST) flags |= CALL_ARG_LVALUE; -  fun_type = new_check_call(fun_name, fun_type, CAR(args), argno, -  flags | (CDR(args)?CALL_NOT_LAST_ARG:0)); -  debug_malloc_touch(fun_type); -  args = CDR(args); -  } -  +     if (!args || !fun_type) {    debug_malloc_touch(fun_type);    return fun_type;    }       (*argno)++;       if (args->token == F_CONSTANT) {    sval = &args->u.sval;    }
pike.git/src/pike_types.c:7104:    if (tmp) free_type(tmp);    } else {    free_type(tmp);    }    }    free_type(fun_type);    return res;    }    }    -  if ((tmp = get_first_arg_type(fun_type, flags))) { +  if ((tmp = get_first_arg_type(fun_type, flags|CALL_NOT_LAST_ARG))) {    struct pike_type *tmp2;      #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " Bad argument.\n");    }   #endif /* PIKE_DEBUG */    yytype_report(REPORT_ERROR, NULL, 0, tmp, NULL, 0, args->type,    0, "Bad argument %d to %S.", *argno, fun_name);   
pike.git/src/pike_types.c:7152:   #endif /* PIKE_DEBUG */    yytype_report(REPORT_ERROR, NULL, 0, NULL,    NULL, 0, args->type,    0, "Too many arguments to %S (expected %d arguments).",    fun_name, *argno - 1);    }    free_type(fun_type);    return NULL;   }    + /* NOTE: fun_type loses a reference. */ + struct pike_type *new_check_call(struct pike_string *fun_name, +  struct pike_type *fun_type, +  node *args, INT32 *argno, INT32 flags) + { +  node *orig_arg_parent = NULL; +  INT32 orig_flags = flags; +  int num_cdr = 0; +  int num_lvalue = 0; +  +  if (!args || !fun_type) { +  debug_malloc_touch(fun_type); +  return fun_type; +  } +  +  orig_arg_parent = args->parent; +  args->parent = NULL; /* End marker. */ +  +  debug_malloc_touch(fun_type); +  +  while (args && fun_type) { +  if ((args->token == F_ARG_LIST) || (args->token == F_LVALUE_LIST)) { +  if (CDR(args)) { +  num_cdr++; +  flags |= CALL_NOT_LAST_ARG; +  } +  if (args->token == F_LVALUE_LIST) { +  num_lvalue++; +  flags |= CALL_ARG_LVALUE; +  } +  if (CAR(args)) { +  CAR(args)->parent = args; +  args = CAR(args); +  continue; +  } else if (CDR(args)) { +  CDR(args)->parent = args; +  args = CDR(args); +  if (!--num_cdr) { +  flags = orig_flags | (num_lvalue?CALL_ARG_LVALUE:0); +  } +  continue; +  } +  } else { +  fun_type = new_check_call_arg(fun_name, fun_type, args, argno, flags); +  debug_malloc_touch(fun_type); +  +  if (!fun_type) return NULL; +  } +  +  do { +  node *prev = args; +  if (args->token == F_LVALUE_LIST) { +  if (!--num_lvalue) { +  flags = orig_flags | (num_cdr?CALL_NOT_LAST_ARG:0); +  } +  } +  args = args->parent; +  if (!args) { +  prev->parent = orig_arg_parent; +  break; +  } +  if ((CAR(args) == prev) && CDR(args)) { +  if (!--num_cdr) { +  flags = orig_flags | (num_lvalue?CALL_ARG_LVALUE:0); +  } +  if (CDR(args) != prev) { +  CDR(args)->parent = args; +  args = CDR(args); +  break; +  } +  /* CAR(args) == CDR(args), so we need to recurse +  * since we can't differentiate otherwise. +  * +  * This should be a quite rare case, and the tree is +  * most likely very shallow, so this should be safe. +  */ +  fun_type = new_check_call(fun_name, fun_type, prev, argno, flags); +  debug_malloc_touch(fun_type); +  +  if (!fun_type) return NULL; +  } +  } while(args); +  } +  +  return fun_type; + } +    struct pike_type *zzap_function_return(struct pike_type *a,    struct pike_type *fun_ret)   {    struct pike_type *ret = NULL;    switch(a->type)    {    case T_SCOPE:    ret = zzap_function_return(a->cdr, fun_ret);    if (!ret) return NULL;    type_stack_mark();