Branch: Tag:

2012-07-11

2012-07-11 13:47:46 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Compiler: Fix recursion in new_check_call(). Fixes [bug 6442 (#6442)].

6918:   }      /* 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;
6931:       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); -  debug_malloc_touch(fun_type); -  args = CDR(args); -  } -  +     if (!args || !fun_type) {    debug_malloc_touch(fun_type);    return fun_type;
7066:    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_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 (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); +  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; +  } +  args = args->parent; +  if (!args) { +  prev->parent = orig_arg_parent; +  break; +  } +  if ((CAR(args) == prev) && CDR(args)) { +  /* NOTE: The above test is NOT SHARED_NODES safe! */ +  args = CDR(args); +  break; +  } +  } while(args); +  } +  +  return fun_type; + } +    struct pike_type *zzap_function_return(struct pike_type *a,    struct pike_type *fun_ret)   {