pike.git / src / pike_types.c

version» Context lines:

pike.git/src/pike_types.c:2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information.   */      #include "global.h"   #include <ctype.h>   #include "svalue.h"   #include "stralloc.h"   #include "pike_types.h" - #include "stuff.h" +    #include "array.h"   #include "program.h"   #include "constants.h"   #include "object.h"   #include "multiset.h"   #include "mapping.h"   #include "pike_macros.h"   #include "pike_error.h"   #include "las.h"   #include "lex.h"   #include "pike_memory.h"   #include "bignum.h"   #include "main.h"   #include "opcodes.h"   #include "cyclic.h"   #include "gc.h"   #include "pike_compiler.h"   #include "block_allocator.h"   #include "bitvector.h" -  + #include "gc_header.h"      #ifdef PIKE_DEBUG   #define PIKE_TYPE_DEBUG   #endif /* PIKE_DEBUG */         /* Number of entries in the struct pike_type hash-table. */   /* 256Kb */   #define PIKE_TYPE_HASH_SIZE 32767   
pike.git/src/pike_types.c:58:   PMOD_EXPORT struct pike_type *type_type_string;   PMOD_EXPORT struct pike_type *mixed_type_string;   PMOD_EXPORT struct pike_type *void_type_string;   PMOD_EXPORT struct pike_type *zero_type_string;   PMOD_EXPORT struct pike_type *inheritable_type_string;   PMOD_EXPORT struct pike_type *typeable_type_string;   PMOD_EXPORT struct pike_type *enumerable_type_string;   PMOD_EXPORT struct pike_type *any_type_string;   PMOD_EXPORT struct pike_type *weak_type_string; /* array|mapping|multiset|function */   struct pike_type *sscanf_type_string; + PMOD_EXPORT struct pike_type *utf8_type_string;      PMOD_EXPORT struct pike_string *literal_string_string;   PMOD_EXPORT struct pike_string *literal_int_string;   PMOD_EXPORT struct pike_string *literal_float_string;   PMOD_EXPORT struct pike_string *literal_function_string;   PMOD_EXPORT struct pike_string *literal_object_string;   PMOD_EXPORT struct pike_string *literal_program_string;   PMOD_EXPORT struct pike_string *literal_array_string;   PMOD_EXPORT struct pike_string *literal_multiset_string;   PMOD_EXPORT struct pike_string *literal_mapping_string;
pike.git/src/pike_types.c:253:    *    */   static struct block_allocator type_allocator = BA_INIT(sizeof(struct pike_type), 128);      PMOD_EXPORT void really_free_pike_type(struct pike_type * t) {    ba_free(&type_allocator, t);   }      ATTRIBUTE((malloc))   PMOD_EXPORT struct pike_type * alloc_pike_type(void) { -  return ba_alloc(&type_allocator); +  struct pike_type *t = ba_alloc(&type_allocator); +  gc_init_marker(t); +  return t;   }      PMOD_EXPORT void count_memory_in_pike_types(size_t *n, size_t *s) {    ba_count_all(&type_allocator, n, s);   }      struct pike_type **pike_type_hash = NULL;   size_t pike_type_hash_size = 0;      void debug_free_type(struct pike_type *t)
pike.git/src/pike_types.c:316:    case PIKE_T_RING:    /* Free car & cdr */    free_type(car);    t = (struct pike_type *) cdr;    debug_free_type_preamble (t);    goto loop;       case PIKE_T_AUTO:    if (!car)    break; -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM:    case T_STRING:    /* Free car */    t = (struct pike_type *) car;    debug_free_type_preamble (t);    goto loop;
pike.git/src/pike_types.c:549: Inside #if defined(PIKE_DEBUG)
     #ifdef PIKE_DEBUG    if ((type == T_OR) && (car->type == T_OR)) {    Pike_fatal("Invalid CAR to OR node.\n");    }   #endif       debug_malloc_pass(t = ba_alloc(&type_allocator));       t->refs = 0; +  gc_init_marker(t);    add_ref(t); /* For DMALLOC... */    t->type = type;    t->flags = 0;    t->car = car;    t->cdr = cdr;       t->hash = hash;    t->next = pike_type_hash[index];    pike_type_hash[index] = t;   
pike.git/src/pike_types.c:600: Inside #if defined(DEBUG_MALLOC)
   case T_NOT:    case T_TYPE:    case T_PROGRAM:    case T_STRING:    case PIKE_T_AUTO:    debug_malloc_pass(car);    break;       case T_ASSIGN:    t->flags |= PT_FLAG_ASSIGN_0 << PTR_TO_INT(car); -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_SCOPE:    debug_malloc_pass(cdr);    break;       case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    debug_malloc_pass(car);    debug_malloc_pass(cdr);    break;   
pike.git/src/pike_types.c:850:    return;    }    if (type == T_OR) {    struct pike_type *t1 = *(Pike_compiler->type_stackp--);    struct pike_type *t2 = *(Pike_compiler->type_stackp--);    low_or_pike_types(t1, t2, 0);    free_type(t2);    free_type(t1);    return;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case PIKE_T_RING:    /* 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,
pike.git/src/pike_types.c:875:    if ((*Pike_compiler->type_stackp)->type != T_OBJECT) {    struct pike_type *t = (*Pike_compiler->type_stackp);    while ((t->type == PIKE_T_NAME) || (t->type == PIKE_T_ATTRIBUTE)) {    t = t->cdr;    }    if (t->type != T_OBJECT) {    /* Not a program type, convert it to a type type. */    type = T_TYPE;    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_STRING:    case PIKE_T_AUTO:    /* Make a new type of the top type, and put it in car. */    *Pike_compiler->type_stackp = mk_type(type,    *Pike_compiler->type_stackp, NULL,    PT_COPY_CAR);
pike.git/src/pike_types.c:1772:    if(**s=='=')    {    ++*s;    internal_parse_type(_s);    push_assign_type(buf[0]);    }else{    push_type(buf[0]);    }    break;    } +  /* FALLTHRU */       default:    bad_type:    push_type(T_MIXED);    my_yyerror("Couldn't parse type. (%s).", buf);    }       while(isspace(**s)) ++*s;   }   
pike.git/src/pike_types.c:2380:    string_builder_sprintf(s, "{ %S = %T }",    (struct pike_string *)t->car, t->cdr);    break;       case PIKE_T_ATTRIBUTE:    {    struct pike_string *deprecated;    MAKE_CONST_STRING(deprecated, "deprecated");    if (((struct pike_string *)t->car) == deprecated) {    string_builder_sprintf(s, "__deprecated__(%T)", t->cdr); +  } else if (t == utf8_type_string) { +  string_builder_sprintf(s, "utf8_string");    } else {    struct svalue sval;    SET_SVAL(sval, PIKE_T_STRING, 0, string,    (struct pike_string *)t->car);    string_builder_sprintf(s, "__attribute__(%O, %T)", &sval, t->cdr);    }    }    break;       case T_FUNCTION:
pike.git/src/pike_types.c:2537:    switch(t->type)    {    case PIKE_T_RING:    return compile_type_to_runtime_type(t->car);       case T_OR:    {    TYPE_T tmp = compile_type_to_runtime_type(t->car);    if(tmp == compile_type_to_runtime_type(t->cdr))    return tmp; -  -  /* FALL_THROUGH */ +     } -  +  /* FALLTHRU */ +     case T_TUPLE:    /* FIXME: Shouldn't occur/should be converted to array? */ -  /* FALL_THROUGH */ +  /* FALLTHRU */    default:    return T_MIXED;       case T_ZERO:    return T_INT;       case T_SCOPE:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    return compile_type_to_runtime_type(t->cdr);
pike.git/src/pike_types.c:2730:    case T_MULTISET:    if (t1->car->type < t2->car->type) {    t = t1;    ret = -1;    break;    } else if (t1->car->type > t2->car->type) {    t = t2;    ret = 1;    break;    } -  /* FALL_THOUGH */ +  /* FALLTHRU */    default:   #if 0    if (pike_types_le(t1, t2)) {    t = t2;    } else if (pike_types_le(t2, t1)) {    t = t1;    } else   #endif /* 0 */    if (t1 < t2) {    t = t1;
pike.git/src/pike_types.c:2868:    free_type(top);    break;    } else if (t->cdr == top->cdr) {    Pike_compiler->type_stackp--;    push_finished_type(t->cdr);    low_or_pike_types(t->car, top->car, zero_implied);    push_type(T_MAPPING);    free_type(top);    break;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    default:    if (t < top) {    Pike_compiler->type_stackp--;    push_finished_type(t);    push_finished_type(top);    free_type(top);    } else {    push_finished_type(t);    }    break;
pike.git/src/pike_types.c:3910:    }       case PIKE_T_RING:    a = a->car;    goto recurse;       case PIKE_T_SCOPE:   #ifdef TYPE_GROUPING    flags |= LE_A_GROUPED;   #endif -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_NAME:    a = a->cdr;    goto recurse;    case PIKE_T_ATTRIBUTE:    if ((b->type == PIKE_T_ATTRIBUTE) && (a->car == b->car)) {    a = a->cdr;    b = b->cdr;    goto recurse;    }    if (!c) {
pike.git/src/pike_types.c:4117:    (!Pike_sp[-1].u.integer)) {    pop_stack();    return 0;    }    pop_stack();    return 1;    case PIKE_T_SCOPE:   #ifdef TYPE_GROUPING    flags |= LE_B_GROUPED;   #endif -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_NAME:    b = b->cdr;    goto recurse;       case T_NOT:    /* Some common cases. */    switch(b->car->type) {    case T_NOT:    b = b->car->car;    goto recurse;
pike.git/src/pike_types.c:4415:    return 0;    }    } else if (flags & LE_TYPE_SVALUE) {    /* Note: flags never has grouping at this point. */    if (!low_pike_types_le(b_tmp, zero_type_string, 0,    flags ^ LE_A_B_SWAPPED)) {    return 0;    }    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case TWOT(T_MANY, T_MANY):    /* check the 'many' type */    if ((a->car->type != T_VOID) && (b->car->type != T_VOID)) {    /* Note: flags never has grouping at this point. */    if (!low_pike_types_le(b->car, a->car, 0, flags ^ LE_A_B_SWAPPED)) {    return 0;    }    } else if ((flags & LE_TYPE_SVALUE) && (a->car->type != b->car->type)) {    if (a->car->type == T_VOID) {    /* Note: flags never has grouping at this point. */
pike.git/src/pike_types.c:4698: Inside #if 0
   yyreport_type(REPORT_WARNING, NULL, 0, b, NULL, 0, a, 0, "Type mismatch");    }   #endif /* 0 */    switch(a->type)    {    case T_FUNCTION:    a = a->cdr;    while(a->type == T_FUNCTION) {    a = a->cdr;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_MANY:    a = a->cdr;    push_finished_type_with_markers(a, a_markers, 0);    return 1;       case T_TYPE:    case T_PROGRAM:    push_finished_type(a->car);    return 1;   
pike.git/src/pike_types.c:4836:    {    add_ref(mixed_type_string);    return mixed_type_string;    }else{    add_ref(ID_FROM_INT(p, i)->type);    return ID_FROM_INT(p, i)->type;    }    }    }    } -  /* FALL_THROUGH */ +  /* FALLTHRU */       default:    add_ref(mixed_type_string);    return mixed_type_string;       case T_MIXED:    if (pragmas & ID_STRICT_TYPES) {    yywarning("Indexing mixed.");    }    add_ref(mixed_type_string);
pike.git/src/pike_types.c:5329:    case PIKE_T_NAME:    case PIKE_T_ATTRIBUTE:    case T_ASSIGN:    case T_SCOPE:    return low_check_indexing(type->cdr, index_type, n);       case T_ARRAY:    if(low_match_types(string_type_string, index_type, 0) &&    low_check_indexing(type->car, index_type, n))    return 1; -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_STRING:    return !!low_match_types(int_type_string, index_type, 0);       case T_OBJECT:    {    struct program *p = id_to_program(CDR_TO_INT(type));    if(p)    {    int i = -1;    /* Check against the LFUN types. */
pike.git/src/pike_types.c:5376:    * - There were complaints when people got compilation errors    * for indexing operations that would always fail.    */    return low_match_types(type->car, index_type, 0) ? 1 : -1;       case T_FUNCTION:    while ((type = type->cdr) && (type->type == T_FUNCTION))    ;    if (!type) return 0;    -  /* FALL_THROUGH */ +  /* FALLTHRU */       case T_MANY:    type = type->cdr;    if (!type || (type->type != T_OBJECT) || !type->car)    return 0;    /* function(... : object(is foo)) -- ie probably program(foo). */    -  /* FALL_THROUGH */ +  /* FALLTHRU */       case T_INT:    case T_PROGRAM:    return !!low_match_types(string_type_string, index_type, 0);       case T_MIXED:    return 1;       default:    return 0;
pike.git/src/pike_types.c:5441:    return low_count_arguments(q->cdr);       default: return MAX_INT32;       case T_FUNCTION:    while(q->type == T_FUNCTION)    {    num++;    q = q->cdr;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_MANY:    q = q->car;    if(q->type != T_VOID) return ~num;    return num;    }   }      /* Count the number of arguments for a funciton type.    * return -1-n if the function can take number of arguments    * >= n (varargs)
pike.git/src/pike_types.c:5553:    return 0;    }   }      /* Get the type for the specified argument in a function type.    * Argument number -1 is the return type.    * True arguments are counted from zero.    */   struct pike_type *get_argument_type(struct pike_type *fun, int arg_no)   { -  struct pike_type *tmp; +  struct pike_type *tmp, *tmp2;       loop:    switch(fun->type) {    case T_OR: -  return or_pike_types(get_argument_type(fun->car, arg_no), -  get_argument_type(fun->cdr, arg_no), +  fun = or_pike_types(tmp = get_argument_type(fun->car, arg_no), +  tmp2 = get_argument_type(fun->cdr, arg_no),    1); -  +  free_type(tmp); +  free_type(tmp2); +  return fun; +     case T_FUNCTION:    if (arg_no > 0) {    arg_no--;    fun = fun->cdr;    goto loop;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_MANY:    if (arg_no < 0) {    add_ref(fun->cdr);    return fun->cdr;    }    add_ref(fun->car);    return fun->car;       case T_MIXED:    add_ref(fun);
pike.git/src/pike_types.c:5800:    case T_PROGRAM:    /* Convert to a function returning an object. */    copy_pike_type(tmp3, soft_type->car); /* Return type */    if ((tmp2 = low_object_lfun_type(tmp3, LFUN_CREATE))) {    soft_type = tmp2;    tmp2 = NULL;    } else {    /* FIXME: Multiple cases. */    soft_type = function_type_string;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_FUNCTION:    case T_MANY:    {    int array_cnt = 0;    int loop_cnt = 0;    while(orig_type->type == T_ARRAY) {    array_cnt++;    orig_type = orig_type->car;    }    if (orig_type->type == T_PROGRAM) {
pike.git/src/pike_types.c:6355:    case PIKE_T_OBJECT:    fun_type = low_object_lfun_type(fun_type, LFUN_CALL);    if (fun_type) goto loop;       /* FIXME: Multiple cases:    * Untyped object. mixed    * Failed to lookup program id. mixed    * Program does not have the lfun `()(). NULL    */    -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_MIXED:    copy_pike_type(res, mixed_type_string);    break;       case PIKE_T_FUNCTION:    /* Note: Use the low variants of pike_types_le and match_types,    * so that markers get set and kept. */    if (match_type_svalue(fun_type->car, flags, sval)) {    add_ref(res = fun_type->cdr);    break;
pike.git/src/pike_types.c:6631:    case PIKE_T_OBJECT:    fun_type = low_object_lfun_type(fun_type, LFUN_CALL);    if (fun_type) goto loop;       /* FIXME: Multiple cases:    * Untyped object. mixed    * Failed to lookup program id. mixed    * Program does not have the lfun `()(). NULL    */    -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_MIXED:    copy_pike_type(res, mixed_type_string);    break;       case PIKE_T_FUNCTION:    case T_MANY:    /* Special case to detect workarounds for the old    * function call checker.    */    tmp = NULL;
pike.git/src/pike_types.c:6721: Inside #if 0
   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) { +  if ((Pike_compiler->compiler_pass == COMPILER_PASS_LAST) && sval) {    while (tmp2->type == PIKE_T_NAME) {    tmp2 = tmp2->cdr;    }       if (tmp2->type == PIKE_T_ATTRIBUTE) {    struct compilation *c = MAYBE_THIS_COMPILATION;    if (c) {    /* Perform extra argument checking based on the attribute. */    ref_push_string((struct pike_string *)tmp2->car);    push_svalue(sval);
pike.git/src/pike_types.c:7094:    break;    case PIKE_T_OBJECT:    fun_type = low_object_lfun_type(fun_type, LFUN_CALL);    if (fun_type) goto loop;    /* FIXME: Multiple cases:    * Untyped object.    * Failed to lookup program id.    * Program does not have the lfun `()().    */    -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_MIXED:    copy_pike_type(res, mixed_type_string);    break;       case PIKE_T_FUNCTION:    do {    if (!match_types(fun_type->car, void_type_string)) {    /* Too few arguments. */    break;    }    fun_type = fun_type->cdr;    } while(fun_type->type == PIKE_T_FUNCTION);    if (fun_type->type != T_MANY) {    /* Still too few arguments. */    break;    } -  +  /* FALLTHRU */    case T_MANY:    copy_pike_type(res, fun_type->cdr);    break;       default:    /* Not a callable. */    break;    }       if (!res) {
pike.git/src/pike_types.c:7217:    } else {    tmp = low_get_first_arg_type(arg_type->car->car,    flags|FILTER_KEEP_VOID);    }    type_stack_mark();    push_finished_type(tmp);    free_type(tmp);    push_type(arg_type->type);    return pop_unfinished_type();    } -  /* FALL_THROUGH */ +  /* FALLTHRU */       case T_ARRAY:    case T_MULTISET:    /* Keep void! */    tmp = low_get_first_arg_type(arg_type->car, flags|FILTER_KEEP_VOID);    type_stack_mark();    push_finished_type(tmp);    free_type(tmp);    push_type(arg_type->type);    return pop_unfinished_type();
pike.git/src/pike_types.c:7246:    tmp = low_get_first_arg_type(arg_type->car, flags|FILTER_KEEP_VOID);    push_finished_type(tmp);    free_type(tmp);    push_type(arg_type->type);    return pop_unfinished_type();       case T_VOID:    if (!(flags & FILTER_KEEP_VOID)) {    return NULL;    } -  /* FALL_THROUGH */ +  /* 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    *
pike.git/src/pike_types.c:7379:    fun_type = low_object_lfun_type(fun_type, LFUN_CALL);    if (fun_type) {    goto loop;    }    /* FIXME: Multiple cases:    * Untyped object.    * Failed to lookup program id.    * Program does not have the lfun `()().    */    -  /* FALL_THROUGH */ +  /* FALLTHRU */    case PIKE_T_MIXED:    copy_pike_type(res, mixed_type_string);    break;       case PIKE_T_FUNCTION:    if (!(flags & CALL_NOT_LAST_ARG) &&    (fun_type->cdr->type == PIKE_T_FUNCTION) &&    !low_match_types(fun_type->cdr->car, void_type_string, 0)) {    /* Last argument and more arguments required. */    res = NULL;    break;    } -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_MANY:    if ((res = fun_type->car)->type == T_VOID) {    res = NULL;    break;    }    res = low_get_first_arg_type(res, 0);    break;       default:    /* Not a callable. */
pike.git/src/pike_types.c:8246:    case T_ASSIGN:    if ((type_string[1] < '0') || (type_string[1] > '9')) {    Pike_fatal("low_make_pike_type(): Bad marker: %d\n", type_string[1]);    }    low_make_pike_type(type_string+2, cont);    push_assign_type(type_string[1]);    break;    case T_OR:    case T_AND:    /* Order independant */ -  /* FALL_THROUGH */ +  /* FALLTHRU */       case T_MANY:    case T_TUPLE:    case T_MAPPING:    case PIKE_T_RING:    /* Order dependant */    low_make_pike_type(type_string+1, cont);    low_make_pike_type(*cont, cont);    push_reverse_type(type);    break;
pike.git/src/pike_types.c:8279:    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':    /* Marker type */ -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_FLOAT:    case T_MIXED:    case T_VOID:    case T_ZERO:    case PIKE_T_UNKNOWN:    /* Leaf type */    *cont = type_string+1;    push_type(type);    break;   
pike.git/src/pike_types.c:8714:    typeable_type_string = CONSTTYPE(tOr4(tPrg(tObj), tObj,    tFuncV(tNone, tOr(tVoid, tMix),    tObj),    tType(tMix)));    enumerable_type_string = CONSTTYPE(tOr3(tString,tInt,tFloat));    any_type_string = CONSTTYPE(tOr(tVoid,tMix));    weak_type_string = CONSTTYPE(tOr4(tArray,tMultiset,tMapping,    tFuncV(tNone,tZero,tOr(tMix,tVoid))));    sscanf_type_string = CONSTTYPE(tFuncV(tStr tAttr("sscanf_format", tStr),    tAttr("sscanf_args", tMix), tIntPos)); +  utf8_type_string = CONSTTYPE(tUtf8Str);       /* add_ref(weak_type_string); *//* LEAK */       literal_string_string = make_shared_string("string");    literal_int_string = make_shared_string("int");    literal_float_string = make_shared_string("float");    literal_function_string = make_shared_string("function");    literal_object_string = make_shared_string("object");    literal_program_string = make_shared_string("program");    literal_array_string = make_shared_string("array");
pike.git/src/pike_types.c:8799:    free_type(typeable_type_string);    typeable_type_string = NULL;    free_type(enumerable_type_string);    enumerable_type_string = NULL;    free_type(any_type_string);    any_type_string = NULL;    free_type(weak_type_string);    weak_type_string = NULL;    free_type(sscanf_type_string);    sscanf_type_string = NULL; +  free_type(utf8_type_string); +  utf8_type_string = NULL;       free_string(literal_string_string); literal_string_string = NULL;    free_string(literal_int_string); literal_int_string = NULL;    free_string(literal_float_string); literal_float_string = NULL;    free_string(literal_function_string); literal_function_string = NULL;    free_string(literal_object_string); literal_object_string = NULL;    free_string(literal_program_string); literal_program_string = NULL;    free_string(literal_array_string); literal_array_string = NULL;    free_string(literal_multiset_string); literal_multiset_string = NULL;    free_string(literal_mapping_string); literal_mapping_string = NULL;
pike.git/src/pike_types.c:8858:    switch(t->type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    res = find_type(t->car, cb);    if (res) return res; -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_SCOPE:    case T_ASSIGN:    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME:    return find_type(t->cdr, cb);       case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:
pike.git/src/pike_types.c:8927:       switch (t->type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING:    visit_type_ref (t->car, REF_TYPE_INTERNAL, extra); -  /* FALL_THROUGH */ +  /* FALLTHRU */    case T_SCOPE:    case T_ASSIGN:    visit_type_ref (t->cdr, REF_TYPE_INTERNAL, extra);    break;    case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM:    case T_STRING:
pike.git/src/pike_types.c:8999: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
   if (t->cdr) gc_mark_type_as_referenced(t->cdr);    break;    case PIKE_T_FUNCTION:    case T_MANY:    case PIKE_T_RING:    case PIKE_T_TUPLE:    case PIKE_T_MAPPING:    case T_OR:    case T_AND:    if (t->cdr) gc_mark_type_as_referenced(t->cdr); -  /* FALL_THOUGH */ +  /* FALLTHROUGH */    case PIKE_T_ARRAY:    case PIKE_T_MULTISET:    case T_NOT:    case PIKE_T_TYPE:    case PIKE_T_PROGRAM:    if (t->car) gc_mark_type_as_referenced(t->car);    break;    }    } GC_LEAVE;    }
pike.git/src/pike_types.c:9084: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP)
      GC_ENTER (t, T_TYPE) {    switch (t->type) {    case T_FUNCTION:    case T_MANY:    case T_TUPLE:    case T_MAPPING:    case T_OR:    case T_AND:    case PIKE_T_RING: +  debug_gc_check (t->car, " as car in a type"); +  debug_gc_check (t->cdr, " as cdr in a type"); +  break;    case PIKE_T_ATTRIBUTE:    case PIKE_T_NAME: -  + #ifdef PIKE_DEBUG +  /* this is a string and without PIKE_DEBUG +  * they are not touched by the GC */    debug_gc_check (t->car, " as car in a type"); -  + #endif    debug_gc_check (t->cdr, " as cdr in a type");    break;    case T_ARRAY:    case T_MULTISET:    case T_NOT:    case T_TYPE:    case T_PROGRAM:    case T_STRING:    case PIKE_T_AUTO:    debug_gc_check (t->car, " as car in a type");
pike.git/src/pike_types.c:9132: Inside #if defined (PIKE_DEBUG) || defined (DO_PIKE_CLEANUP) and #if defined(PIKE_DEBUG)
   Pike_fatal("gc_check_type: "    "Unhandled type-node: %d\n", t->type);    break;   #endif /* PIKE_DEBUG */    }    } GC_LEAVE;   }      void gc_check_all_types (void)   { -  unsigned INT32 e; +  size_t e;    for(e=0;e<=pike_type_hash_size;e++)    {    struct pike_type *t; -  for(t = pike_type_hash[e]; t; t=t->next) gc_check_type (t); +  for(t = pike_type_hash[e]; t; t=t->next) { +  if (gc_keep_markers) { +  /* Make sure that leaked types also have markers at cleanup... */ +  (void)get_marker(t);    } -  +  gc_check_type(t);    } -  +  } + }      #endif /* PIKE_DEBUG || DO_PIKE_CLEANUP */