pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:12056:    simple_describe_type(arg_type);    fprintf(stderr, " against function type ");    simple_describe_type(fun_type);    fprintf(stderr, ".\n");    remap_flags |= PT_FLAG_REMAP_TRACE;    }   #endif /* PIKE_DEBUG */       /* No need to perform advanced checking in the trivial case... */    if (arg_type != (tmp2 = fun_type->car)) { +  if (tmp2 == void_type_string) { +  /* No more arguments accepted. */ +  goto no_match; +  }    if (flags & CALL_ARG_LVALUE) {    /* For lvalues (ie sscanf) the direction is reversed. */    struct pike_type *tmp3 = tmp2;    tmp2 = arg_type;    arg_type = tmp3;       remap_flags ^= PT_FLAG_REMAP_SWAP_MARKERS;    }    if (!tmp2) {    if (flags & CALL_STRICT) goto no_match; -  } else if (tmp2 == void_type_string) { -  /* No more arguments accepted. */ -  goto no_match; +     } else {    struct pike_type *bin_t =    low_type_binop(PT_BINOP_MINUS,    arg_type, tmp2, &remap,    PT_FLAG_CMP_VOID_IS_ZERO,    PT_FLAG_CMP_VOID_IS_ZERO,    remap_flags|PT_FLAG_REMAP_EVAL_MARKERS);       if (bin_t) {    /* Partial or strict mismatch. */
pike.git/src/pike_types.cmod:12198:   #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");
pike.git/src/pike_types.cmod:12232:    if (l_flag>2) {    fprintf(stderr, "%*s==> ", indent*2, "");    simple_describe_type(res);    fprintf(stderr, "\n");    }   #endif /* PIKE_DEBUG */       return res;   }    - /* Check whether arg_type may be used as the type of the first argument + /** +  * Check whether arg_type may be used as the type of the first argument    * in a call to fun_type.    *    * If the argument is a constant, sval will contain a pointer to it.    *    * Returns NULL on failure.    *    * Returns continuation function type on success.    */   struct pike_type *low_new_check_call(struct pike_type *fun_type,    struct pike_type *arg_type,
pike.git/src/pike_types.cmod:12419:    push_finished_type(tmp);    free_type(tmp);       /* NB: Zero always succeeds. */    push_type(T_OR);    tmp = pop_unfinished_type();    }    return tmp;   }    - /* Return the return type for the function type fun_type, if + /** +  * Return the return type for the function type fun_type, if    * no further arguments are passed.    *    * Returns NULL if more arguments are required.    *    * Returns a the type of the return value otherwise.    */   struct pike_type *new_get_return_type(struct pike_type *fun_type,    INT32 flags)   {    struct compilation *c = MAYBE_THIS_COMPILATION;
pike.git/src/pike_types.cmod:12667:    push_finished_type_with_markers(res, a_markers, 0);       free_type(res);       while(array_cnt--) {    push_unlimited_array_type(PIKE_T_ARRAY);    }      #ifdef PIKE_DEBUG    if (l_flag>2) { -  fprintf(stderr, "Done.\n"); +  fprintf(stderr, " Done. Return type is "); +  simple_describe_type(peek_type_stack()); +  fprintf(stderr, "\n");    }   #endif /* PIKE_DEBUG */       return pop_unfinished_type();   }    - /* Adjust the argument type. + /** +  * Adjust the argument type.    *    * Get rid of void and setvar.    */   static struct pike_type *low_get_first_arg_type(struct pike_type *arg_type,    INT32 flags)   {    struct pike_type *tmp;    struct pike_type *tmp2;    struct pike_type *res;   
pike.git/src/pike_types.cmod:12781:    }    /* FALLTHRU */    default:    break;    }    }    add_ref(arg_type);    return arg_type;   }    - /* Return the type of the first argument to a function of the type fun_type + /** +  * Return the type of the first argument to a function of the type fun_type    *    * Returns NULL on failure. Eg not callable or no more args accepted.    *    * Returns the argument type on success. -  +  * +  * @note +  * Returns void_type_string if no more args accepted in +  * CALL_ARG_LVALUE mode.    */   struct pike_type *get_first_arg_type(struct pike_type *fun_type,    INT32 flags)   {    struct pike_type *res = NULL;    struct pike_type *tmp;    struct pike_type *tmp2;    loop:    /* Get rid of the array levels. */    while(fun_type->type == PIKE_T_ARRAY) {
pike.git/src/pike_types.cmod:12857:    break;    }    if (!(tmp = get_first_arg_type(fun_type->cdr, flags))) {    if (flags & CALL_ARG_LVALUE) {    break;    }    free_type(res);    res = NULL;    break;    } +  if (flags & CALL_ARG_LVALUE) { +  /* Handle end of arguments marker. */ +  if (res == void_type_string) { +  free_type(tmp); +  break; +  } +  if (tmp == void_type_string) { +  free_type(res); +  res = tmp; +  break; +  } +  }    /* NOTE: OR and not AND in some cases!    *    * !function(!string:mixed)&function(string|int:string)    * ==>    * string | string|int    *    * This is however not true in the case where neither is inverted:    *    * function(attribute(sprintf_args, mixed)...:string) &    * function(object|string:string)
pike.git/src/pike_types.cmod:12942:    if (!(flags & CALL_NOT_LAST_ARG) &&    (fun_type->cdr->type == PIKE_T_FUNCTION) &&    !match_types(fun_type->cdr->car, void_type_string)) {    /* Last argument and more arguments required. */    res = NULL;    break;    }    /* FALLTHRU */    case T_MANY:    if (!(res = fun_type->car) || (res->type == T_VOID)) { +  if ((flags & CALL_ARG_LVALUE) && res) { +  add_ref(res); +  break; +  }    res = NULL;    break;    }    res = low_get_first_arg_type(res, 0);    break;       default:    /* Not a callable. */    break;    }
pike.git/src/pike_types.cmod:13164:    } else {    free_type(tmp);    }    }    free_type(fun_type);       return res;    }    }    -  if ((tmp = get_first_arg_type(fun_type, flags|CALL_NOT_LAST_ARG))) { +  if ((tmp = get_first_arg_type(fun_type, flags|CALL_NOT_LAST_ARG)) && +  (tmp != void_type_string)) {    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.", cs->argno, fun_name);   
pike.git/src/pike_types.cmod:13199:       return tmp2;    }   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "\n Failed to create continuation type.\n");    }   #endif /* PIKE_DEBUG */    free_type(tmp);    } else { +  free_type(tmp); +    #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " Too many arguments.\n");    }   #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, cs->argno - 1);    }