ooc-lang / rock

:ocean: self-hosted ooc compiler that generates c99
http://ooc-lang.org/
MIT License
404 stars 40 forks source link

Add implict cast to reduce GCC warnings #917

Open horasal opened 9 years ago

horasal commented 9 years ago

Currently, compiling rock will yield plenty of warnings. Almost all the warnings are caused by the common root of object.

In OOC, we can assign a object with different type to current variable. Howover, even they have a common root, gcc will throw warnings because the definitions in C are usually different.

We should perform a implict cast to avoid this type of warnings.

Example warnings

assignment from incompatible pointer type
pointer type mismatch in conditional expression
initialization from incompatible pointer type [-Wincompatible-pointer-types]

Sample code:(from BinaryOp.ooc)

    replace: func (oldie, kiddo: Node) -> Bool {
        match oldie {
            case left  =>
                left = kiddo
                refresh()
                true
            case right =>
                right = kiddo 
                refresh()
                true
            case =>
                false
        }
    }

left and right is defined as Expression, however, kiddo is Node, assigning Node to Expression sometimes is dangerous.

from FunctionDecl.ooc

            closureElements := [
                varAcc
                NullLiteral new(token)
            ] as ArrayList<Expression>

Here we are casting array to ArrayList. Commonroot of variableAccess and NullLiteral is Expression, however, there is no casting of varAcc and NullLiteral new when we create the array.

Another warning:

middle/StringLiteral.ooc: In function ‘rock_middle_StringLiteral__InterpolatedStringLiteral_replace’:
middle/StringLiteral.ooc:307:140: warning: passing argument 2 of ‘((rock_middle_Node__NodeClass *)((lang_types__Object *)this)->class)->replace’ from incompatible pointer type [-Wincompatible-pointer-types]
middle/StringLiteral.ooc:307:140: note: expected ‘rock_middle_Node__Node * {aka struct _rock_middle_Node__Node *}’ but argument is of type ‘rock_middle_Statement__Statement * {aka struct _rock_middle_Statement__Statement *}’

Related code:

    replace: func (oldie, kiddo: Statement) -> Bool {
        match oldie {
            case e1: Expression =>
                match kiddo {
                    case e2: Expression =>
                        return expressions replace(e1, e2)
                }
        }
        false
    }

replace is declared in Node which looks like thin in Node.ooc:

    replace: abstract func (oldie, kiddo: Node) -> Bool

However StringLiteral declares replace with argument Statement. I think it is not bad. But at least we need some automatical instanceOf? and as.

The real reason I open this issue is that there are so many "intended" warnings so we are getting used to ignore all of them. Recently, I found the following piece of code: (in ClassDecl.ooc)

    getBaseClass: func (fDecl: FunctionDecl, withInterfaces: Bool, comeBack: Bool*) -> ClassDecl {
        sRef := getSuperRef() as ClassDecl
        // An interface might not yet be resolved.
        comeBack@ = false 
        // first look in the supertype, if any
        if(sRef != null) {

            base := sRef getBaseClass(fDecl, comeBack)
            if (comeBack@) { // ugly_
                return null
            }
            if(base != null) {
                return base
            }
        }

        // look in interface types, if any
        if(withInterfaces && getNonMeta()) for(interfaceType in getNonMeta() interfaceTypes) {
            iRef := interfaceType getRef() as ClassDecl // missing interface
            if (!iRef) { // ugly_
                comeBack=true
                return null
            }

            if(!iRef isMeta) iRef = iRef getMeta()
            if(iRef != null) {
                base := iRef getBaseClass(fDecl, comeBack)
                if (comeBack) { // ugly_
                    comeBack=true
                    return null
                }
                if(base != null) {
                    return base
                }
            }
        }

        // if all else fails, try in this
        finalScore := 0
        if(getFunction(fDecl name, fDecl suffix ? fDecl suffix : "", null, false, finalScore&) != null) {
            return this
        }

        return null
    }

comeBack is a pointer of Bool, but in some lines it is used without dereference. GCC does throw a warning on these codes but there's no chance to figure it out. Because all other warnings are useless.

davidhesselbom commented 9 years ago

I haven't given much attention to the warnings generated when building rock itself, but I can attest that important warnings are easily missed in a flood of unimportant ones that you learn to ignore.