github-vet / github-vet/rangeloop-pointer-findings
AZHenley/knox: typechecker/typechecker.go; 84 LoC
- Dominant language
- No language data
- Stars
- 0
- Forks
- 0
- PR merge metrics
- PR metrics pending
Description
Found a possible issue in [AZHenley/knox](https://www.github.com/AZHenley/knox) at [typechecker/typechecker.go](https://github.com/AZHenley/knox/blob/f7e854c0fbe0f15c7e68f8e030eb223718a6ba55/typechecker/typechecker.go#L24-L107)
Below is the message reported by the analyzer for this snippet of code. Beware that the analyzer only reports the first
issue it finds, so please do not limit your consideration to the contents of the below message.
> reference to child is reassigned at line 94
[Click here to see the code in its original context.](https://github.com/AZHenley/knox/blob/f7e854c0fbe0f15c7e68f8e030eb223718a6ba55/typechecker/typechecker.go#L24-L107)
Click here to show the 84 line(s) of Go which triggered the analyzer.
```go
for _, child := range node.Children {
if child.Type == ast.EXPRESSION {
exprType := getType(&child.Children[0])
// TODO: Handle for, return
if node.Type == ast.VARDECL {
// TODO: Handle multiple assignment.
leftType := declType(node)
//fmt.Println("Left: " + leftType.fullName)
//fmt.Println("Right: " + exprType.fullName)
if !compareTypes(leftType, exprType) { // Do the types match?
abortMsgf(node, "Mismatched types: %s and %s", leftType.fullName, exprType.fullName)
}
if leftType.isClass && !child.Symbols.IsDeclared(leftType.name) {
abortMsgf(node, "Undeclared type: %s", leftType.name)
}
} else if node.Type == ast.VARASSIGN {
// TODO: Fix member access bug.
//decl := child.Symbols.LookupSymbol(node.Children[0].Children[0].TokenStart.Literal)
//if decl == nil {
// abortMsgf("Referencing undeclared variable: %s", node.Children[0].Children[0].TokenStart.Literal)
//}
//leftType := declType(decl)
leftType := getType(&node.Children[0])
if !compareTypes(leftType, exprType) { // Do the types match?
abortMsgf(node, "Mismatched types: %s and %s", leftType.fullName, exprType.fullName)
}
} else if node.Type == ast.IFSTATEMENT || node.Type == ast.WHILESTATEMENT {
if !compareTypes(exprType, prim.typeBOOL) {
abortMsg(node, "Conditionals require boolean expressions.")
}
}
// } else if child.Type == ast.FUNCCALL { // Handles funccall outside of an expression.
// name := child.Children[0].TokenStart.Literal
// declNode := node.Symbols.LookupSymbol(name)
// // Compare types between args and params.
// checkFuncCall(&child, declNode)
// // Check that nothing is returned.
// if name != "print" && (len(declType(declNode).inner) > 1 || !compareTypes(&declType(declNode).inner[0], typeVOID)) {
// abortMsg("Function call return values must be used.")
// }
} else if child.Type == ast.JUMPSTATEMENT {
if child.TokenStart.Literal == "return" {
// TODO: Support multiple return types.
returnType := buildTypeList(&child)
funcReturnType := buildReturnList(¤tFunc.Children[2])
if compareTypes(funcReturnType, prim.typeVOID) && returnType.fullName == "" { // Check for return; and void type.
} else if !compareTypes(&returnType.inner[0], &funcReturnType.inner[0]) {
// TODO: Comparing the inner[0] is correct for single return types, but won't work for multiple. Need to expand compareType to handle this. buildTypeList and buildReturnList should probably not use inner for single return types, which would solve literals and simple types, then set isMulti to true and expand compareTypes to handle recursively comparing inner for multi.
abortMsgf(node, "Incorrect return type: %v when expecting %v.", returnType.inner[0].fullName, funcReturnType.inner[0].fullName)
}
}
} else if node.Type == ast.FORSTATEMENT {
// TODO: Right should be a list. Left type should be right inner type.
// TODO: Is this working?
left := declType(&node.Children[0])
right := getType(&node.Children[1])
fmt.Println("Debugging...", right.fullName, right.isList, right.isClass, right.isPrimitive)
if !right.isList && !right.isMap {
abortMsg(node, "For loop requires a list or map")
}
if !compareTypes(left, &right.inner[0]) {
abortMsg(node, "For loop element is incorrect type")
}
} else if child.Type == ast.FUNCDECL {
currentFunc = &child
typecheck(&child)
} else if child.Type == ast.CLASS {
currentClass = &child
typecheck(&child)
} else if child.Type == ast.LEFTEXPR {
only := getType(&child.Children[0])
if !compareTypes(only, prim.typeVOID) {
abortMsg(node, "Expression must be of void type, not "+only.fullName)
}
} else {
typecheck(&child)
}
}
```
Leave a reaction on this issue to contribute to the project by classifying this instance as a **Bug** :-1:, **Mitigated** :+1:, or **Desirable Behavior** :rocket:
See the descriptions of the classifications [here](https://github.com/github-vet/rangeclosure-findings#how-can-i-help) for more information.
commit ID: f7e854c0fbe0f15c7e68f8e030eb223718a6ba55
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.