this revision breaks parrot on msvc (and i suspect other c89-compliant
compilers--sometimes i wonder if there are any others!)

in particular, in the following chunk (snipped from overall patch for
brevity) the UNUSED(foo) macro is used before variables are declared
in the body of the find_outer() function. fixing that (by moving
C<UNUSED(interp);> below the declarations leads to problems with
another chunk, which i describe after this one.

Modified: trunk/compilers/imcc/pbc.c
==============================================================================
--- trunk/compilers/imcc/pbc.c  (original)
+++ trunk/compilers/imcc/pbc.c  Wed May 16 13:58:40 2007
@@ -565,71 +600,87 @@
                    lex_info = pmc_new_noinit(interp, lex_info_id);
                    VTABLE_init_pmc(interp, lex_info, sub);
                }
+
+                /* at least one lexical name */
                n = r->reg;
-                assert(n); /* at least one lexical name */
+                assert(n);
+
                while (n) {
                    k = n->color;
                    assert(k >= 0);
+
                    lex_name = constants[k]->u.string;
                    assert(PObj_is_string_TEST(lex_name));
+
                    IMCC_debug(interp, DEBUG_PBC_CONST,
                            "add lexical '%s' to sub name '%s'\n",
                            n->name, (char*)PMC_sub(sub)->name->strstart);
-                    (decl_func)(interp,
-                                lex_info, lex_name, r->color);
+
+                    (decl_func)(interp, lex_info, lex_name, r->color);
+
                    /* next possible name */
                    n = n->reg;
                }
            }
        }
    }
+
    if (!lex_info && (unit->outer || need_lex)) {
        lex_info = pmc_new_noinit(interp, lex_info_id);
        VTABLE_init_pmc(interp, lex_info, sub);
    }
+
    return lex_info;
}

static PMC*
find_outer(Interp *interp, IMC_Unit *unit)
{
-    struct subs *s;
+    UNUSED(interp);
+
+    subs_t *s;
    SymReg *sub;
-    size_t len;
-    PMC *current;
+    size_t  len;
+    PMC    *current;
    STRING *cur_name;

    if (!unit->outer)
        return NULL;
+
    /*
     * we need that the :outer sub is already compiled,
     * because we are freezing the outer Sub PMC along with this
     * one
     */
-    UNUSED(interp);
+
    len = strlen(unit->outer->name);
+
    if (!len)
        return NULL;
+
    for (s = globals.cs->first; s; s = s->next) {
        sub = s->unit->instructions->r[0];
+
        if (!strcmp(sub->name, unit->outer->name)) {
            PObj_get_FLAGS(s->unit->sub_pmc) |= SUB_FLAG_IS_OUTER;
            return s->unit->sub_pmc;
        }
    }
-    /*
-     * could be eval too - look, if :outer is the currentsub
-     */
+
+    /* could be eval too; check if :outer is the current sub */
    current = CONTEXT(interp->ctx)->current_sub;
+
    if (! current)
        IMCC_fatal(interp, 1,
                   "Undefined :outer sub '%s'.\n",
                   unit->outer->name);
+
    cur_name = PMC_sub(current)->name;
+
    if (cur_name->strlen == len &&
-            !memcmp((char*)cur_name->strstart, unit->outer->name, len)) {
+            !memcmp((char*)cur_name->strstart, unit->outer->name, len))
        return current;
-    }
+
    return NULL;
}



the chunk below causes msvc to output the following:

compilers\imcc\pbc.c
compilers\imcc\pbc.c(921) : error C2275: 'SymReg' : illegal use of this type as
an expression
       d:\usr\local\parrot\head\compilers\imcc\symreg.h(80) : see declaration o
f 'SymReg'
compilers\imcc\pbc.c(921) : error C2065: 'reg' : undeclared identifier
compilers\imcc\pbc.c(923) : error C2223: left of '->nextkey' must point to struc
t/union
compilers\imcc\pbc.c(927) : warning C4047: '=' : 'SymReg *' differs in levels of
indirection from 'int'
NMAKE : fatal error U1077: 'D:\usr\local\perl\bin\perl.exe' : return code '0x2'
Stop.

i've tried various things to get this to work, but i can't find the
magic incantation.

@@ -834,47 +898,57 @@
build_key(Interp *interp, SymReg *key_reg)
{
#define KEYLEN 21
-    opcode_t key[KEYLEN], *pc, size;
-    char s_key[KEYLEN*10];
-    int key_length;     /* P0["hi;there"; S0; 2] has length 3 */
-    char *s;
-    int k;
-    SymReg *r, *reg;
-    int var_type, slice_bits, type;
-
-    pc = key + 1;       /* 0 is length */
-    s = s_key;          /* stringified key */
-    *s = 0;
-    reg = key_reg->set == 'K' ? key_reg->nextkey : key_reg;
+    char      s_key[KEYLEN * 10];
+    opcode_t  key[KEYLEN];
+    opcode_t  size;
+    int       key_length;     /* P0["hi;there"; S0; 2] has length 3 */
+    int       k;
+    SymReg   *r;
+    int       var_type, slice_bits, type;
+
+    /* 0 is length */
+    opcode_t *pc = key + 1;
+
+    /* stringified key */
+    char     *s  = s_key;
+    *s           = 0;
+
+    SymReg *reg  = key_reg->set == 'K' ? key_reg->nextkey : key_reg;

    for (key_length = 0; reg ; reg = reg->nextkey, key_length++) {
        if ((pc - key - 2) >= KEYLEN)
            IMCC_fatal(interp, 1, "build_key:"
                    "key too complex increase KEYLEN\n");
        r = reg;
+
        /* if key is a register, the original sym is in r->reg */
        type = r->type;
+
        if (r->reg)
            r = r->reg;
-        var_type = type & ~VT_SLICE_BITS;
-        slice_bits = type & VT_SLICE_BITS;
+
+        var_type   = type & ~VT_SLICE_BITS;
+        slice_bits = type &  VT_SLICE_BITS;
+
        switch (var_type) {
            case VTIDENTIFIER:       /* P[S0] */
-            case VTPASM:       /* P[S0] */
-            case VTREG:        /* P[S0] */
+            case VTPASM:             /* P[S0] */
+            case VTREG:              /* P[S0] */
                if (r->set == 'I')
                    *pc++ = PARROT_ARG_I | slice_bits;    /* register type */
                else if (r->set == 'S')
                    *pc++ = PARROT_ARG_S | slice_bits;
                else
-                    IMCC_fatal(interp, 1, "build_key: "
-                            "wrong register set\n");
+                    IMCC_fatal(interp, 1, "build_key: wrong register set\n");
+
                /* don't emit mapped regs in key parts */
                if (r->color < 0)
                    *pc++ = -1 - r->color;
                else
                    *pc++ = r->color;
+
                sprintf(s+strlen(s), "%c%d", r->set, (int)r->color);
+
                IMCC_debug(interp, DEBUG_PBC_CONST,
                        " keypart reg %s %c%d slice %s\n",
                        r->name, r->set, (int)r->color,


this situation is *extremely* frustrating. the temporary workaround is
to revert this patch until it works everywhere. the solution is to
find a way to make gcc (and other) compilers comply with our most
important coding standard: C89 compliance.

i have all too often experienced broken builds because somebody has
committed non-C89 code. i'm tired of being punished for having a
strict compiler. gcc has flags for this--let's use them!

i'll happily pitch in to the extent that i'm able, but i can't be
responsible for the whole effort. we need the whole team to focus on
this problem, so we can finally resolve this long-standing issue.
~jerry

Reply via email to