Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b7daf60 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 4067

* changes:
  Improve symbol-related error checking
parents 4da9e183 a6baa23f
Loading
Loading
Loading
Loading
+105 −34
Original line number Diff line number Diff line
@@ -1312,6 +1312,12 @@ class Compiler : public ErrorSink {
            }
        }

        String& operator=(const String& other) {
            clear();
            appendBytes(other.getUnwrapped(), other.len());
            return *this;
        }

        inline char* getUnwrapped() const {
            return mpBase;
        }
@@ -1439,6 +1445,12 @@ class Compiler : public ErrorSink {
            return result;
        }

        void forEach(bool (*callback)(String* key, V* value, void* context),
                     void* context) {
            hashmapForEach(mpMap, (bool (*)(void*, void*, void*)) callback,
                           context);
        }

    protected:

        void init(size_t initialCapacity) {
@@ -1670,11 +1682,21 @@ class Compiler : public ErrorSink {
            return addImp(0, pName);
        }

        void forEachGlobal(
            bool (*callback)(String* key, VariableInfo* value, void* context),
            void* context) {
            mStack.get(0).pTable->forEach(callback, context);
        }

    private:
        VariableInfo* addImp(int entryIndex, String* pName) {
            Entry e = mStack.get(entryIndex);
            SymbolTable* pTable = e.pTable;
            if (pTable->contains(pName)) {
                return NULL;
            }
            VariableInfo* v = new VariableInfo();

            delete pTable->put(pName, v);
#if 0
            fprintf(stderr, "Add \"%s\" %08x level %d\n", pName->getUnwrapped(), v, e.level);
@@ -2044,6 +2066,7 @@ class Compiler : public ErrorSink {
    void unary(intptr_t l) {
        intptr_t n, t, a;
        int c;
        String tString;
        t = 0;
        n = 1; /* type of expression 0 = forward, 1 = value, other =
         lvalue */
@@ -2063,6 +2086,7 @@ class Compiler : public ErrorSink {
            c = tokl;
            a = tokc;
            t = tok;
            tString = mTokenString;
            next();
            if (t == TOK_NUM) {
                pGen->li(a);
@@ -2112,14 +2136,15 @@ class Compiler : public ErrorSink {
            } else {
                if (t == TOK_UNDEFINED_SYMBOL) {
                    t = (intptr_t) mSymbolTable.addGlobal(
                        new String(mTokenString));
                        new String(tString));
                }

                n = *(int *) t;
                n = (intptr_t) ((VariableInfo*) t)->pAddress;
                /* forward reference: try dlsym */
                if (!n) {
                    n = (intptr_t) dlsym(RTLD_DEFAULT,
                                         mTokenString.getUnwrapped());
                                         tString.getUnwrapped());
                    ((VariableInfo*) t)->pAddress = (void*) n;
                }
                if ((tok == '=') & l) {
                    /* assignment */
@@ -2128,6 +2153,9 @@ class Compiler : public ErrorSink {
                    pGen->storeR0(n);
                } else if (tok != '(') {
                    /* variable */
                    if (!n) {
                        error("Undefined variable %s", tString.getUnwrapped());
                    }
                    pGen->loadR0(n, tokl == 11, tokc);
                    if (tokl == 11) {
                        next();
@@ -2216,7 +2244,7 @@ class Compiler : public ErrorSink {
        return pGen->gtst(0, 0);
    }

    void block(intptr_t l) {
    void block(intptr_t l, bool outermostFunctionBlock) {
        intptr_t a, n, t;

        if (tok == TOK_IF) {
@@ -2224,12 +2252,12 @@ class Compiler : public ErrorSink {
            skip('(');
            a = test_expr();
            skip(')');
            block(l);
            block(l, false);
            if (tok == TOK_ELSE) {
                next();
                n = pGen->gjmp(0); /* jmp */
                pGen->gsym(a);
                block(l);
                block(l, false);
                pGen->gsym(n); /* patch else jmp */
            } else {
                pGen->gsym(a); /* patch if test */
@@ -2259,18 +2287,22 @@ class Compiler : public ErrorSink {
                }
            }
            skip(')');
            block((intptr_t) &a);
            block((intptr_t) &a, false);
            pGen->gjmp(n - codeBuf.getPC() - pGen->jumpOffset()); /* jmp */
            pGen->gsym(a);
        } else if (tok == '{') {
            if (! outermostFunctionBlock) {
                mSymbolTable.pushLevel();
            }
            next();
            /* declarations */
            localDeclarations();
            while (tok != '}' && tok != EOF)
                block(l);
                block(l, false);
            skip('}');
            if (! outermostFunctionBlock) {
                mSymbolTable.popLevel();
            }
        } else {
            if (tok == TOK_RETURN) {
                next();
@@ -2350,18 +2382,22 @@ class Compiler : public ErrorSink {
        }
    }

    void defineGlobalSymbol() {
        if (tok == TOK_UNDEFINED_SYMBOL) {
            // TODO: don't allow multiple definitions at same level.
    void addGlobalSymbol() {
        tok = (intptr_t) mSymbolTable.addGlobal(
            new String(mTokenString));
        reportIfDuplicate();
    }

    void reportIfDuplicate() {
        if (!tok) {
            error("Duplicate definition of %s", mTokenString.getUnwrapped());
        }
    }

    void defineLocalSymbol() {
        // TODO: don't allow multiple definitions at same level.
    void addLocalSymbol() {
        tok = (intptr_t) mSymbolTable.addLocal(
                new String(mTokenString));
        reportIfDuplicate();
    }

    void localDeclarations() {
@@ -2371,10 +2407,11 @@ class Compiler : public ErrorSink {
        while (acceptType(base)) {
            while (tok != ';') {
                Type t = acceptPointerDeclaration(t);
                defineLocalSymbol();
                addLocalSymbol();
                if (tok) {
                    loc = loc + 4;
                    *(int *) tok = -loc;

                }
                next();
                if (tok == ',')
                    next();
@@ -2388,29 +2425,39 @@ class Compiler : public ErrorSink {
            Type base;
            expectType(base);
            Type t = acceptPointerDeclaration(t);
            defineGlobalSymbol();
            if (tok == TOK_UNDEFINED_SYMBOL) {
                addGlobalSymbol();
            }
            VariableInfo* name = (VariableInfo*) tok;
            if (name && name->pAddress) {
                error("Already defined global %s",
                      mTokenString.getUnwrapped());
            }
            next();
            if (tok == ',' || tok == ';') {
                // it's a variable declaration
                for(;;) {
                    if (name) {
                        name->pAddress = (int*) allocGlobalSpace(4);
                    }
                    if (tok != ',') {
                        break;
                    }
                    skip(',');
                    t = acceptPointerDeclaration(t);
                    defineGlobalSymbol();
                    addGlobalSymbol();
                    name = (VariableInfo*) tok;
                    next();
                }
                skip(';');
            } else {
                if (name) {
                    /* patch forward references (XXX: does not work for function
                     pointers) */
                    pGen->gsym((int) name->pForward);
                    /* put function address */
                    name->pAddress = (void*) codeBuf.getPC();
                }
                skip('(');
                mSymbolTable.pushLevel();
                intptr_t a = 8;
@@ -2419,10 +2466,12 @@ class Compiler : public ErrorSink {
                    Type aType;
                    expectType(aType);
                    aType = acceptPointerDeclaration(aType);
                    defineLocalSymbol();
                    addLocalSymbol();
                    if (tok) {
                        /* read param name and compute offset */
                        *(int *) tok = a;
                        a = a + 4;
                    }
                    next();
                    if (tok == ',')
                        next();
@@ -2431,7 +2480,7 @@ class Compiler : public ErrorSink {
                skip(')');
                rsym = loc = 0;
                a = pGen->functionEntry(argCount);
                block(0);
                block(0, true);
                pGen->gsym(rsym);
                pGen->functionExit(argCount, a, loc);
                mSymbolTable.popLevel();
@@ -2551,6 +2600,7 @@ public:
        inp();
        next();
        globalDeclarations();
        checkForUndefinedForwardReferences();
        result = pGen->finishCompile();
        if (result == 0) {
            if (mErrorBuf.len()) {
@@ -2560,6 +2610,27 @@ public:
        return result;
    }

    void checkForUndefinedForwardReferences() {
        mSymbolTable.forEachGlobal(static_ufrcFn, this);
    }

    static bool static_ufrcFn(String* key, VariableInfo* value,
                                                 void* context) {
        Compiler* pCompiler = (Compiler*) context;
        return pCompiler->undefinedForwardReferenceCheck(key, value);
    }

    bool undefinedForwardReferenceCheck(String* key, VariableInfo* value) {
#if 0
        fprintf(stderr, "%s 0x%8x 0x%08x\n", key->getUnwrapped(),
                value->pAddress, value->pForward);
#endif
        if (!value->pAddress && value->pForward) {
            error("Undefined forward reference: %s", key->getUnwrapped());
        }
        return true;
    }

    int dump(FILE* out) {
        fwrite(codeBuf.getBase(), 1, codeBuf.getSize(), out);
        return 0;
+8 −2
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@ int a;

int f() {
    int a;
    printf("f 0: a = %d b = %d\n", a, b);
    // Undefined variable b
    // printf("f 0: a = %d b = %d\n", a, b);
    printf("f 0: a = %d\n", a);
    a = 2;
    printf("f 1: a = %d\n", a);
}
@@ -14,19 +16,23 @@ int g(int a) {
}

int h(int a) {
    int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol
    // int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol

    printf("h 0: a = %d\n", a);
    a = 4;
    printf("h 1: a = %d\n", a);
}

// Already defined global 
// int h() {}
int globCheck() {
    fprintf(stdout, "globCheck()\n");
}

int fwdCheck() {
    b();
    // Undefined forward reference
    // c();
}

int b() {