lang: funcs: core: fmt: Fix printf unification bug

We also add a backup fix to avoid a panic in case we ever hit a new
unification bug that lets something through, we can at least turn it
into a runtime issue. This adds a test as well.
This commit is contained in:
James Shubin
2023-08-13 17:42:23 -04:00
parent 1f53fd85b4
commit b8d87e2d5a
2 changed files with 15 additions and 0 deletions

View File

@@ -199,6 +199,11 @@ func (obj *PrintfFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, erro
invariants = append(invariants, invar) invariants = append(invariants, invar)
} }
// catch situations like `printf("%d%d", 42)`
if len(cfavInvar.Args) <= i+1 {
return nil, fmt.Errorf("more specifiers (%d) than values (%d)", len(typList), len(cfavInvar.Args)-1)
}
// add the relationships to the called args // add the relationships to the called args
invar = &interfaces.EqualityInvariant{ invar = &interfaces.EqualityInvariant{
Expr1: cfavInvar.Args[i+1], Expr1: cfavInvar.Args[i+1],
@@ -557,6 +562,11 @@ func compileFormatToString(format string, values []types.Value) (string, error)
} }
inType = false // done inType = false // done
if ix >= len(values) {
// programming error, probably in type unification
return "", fmt.Errorf("more specifiers (%d) than values (%d)", ix+1, len(values))
}
// check the type (if not a variant) matches what we have... // check the type (if not a variant) matches what we have...
if typ == types.TypeVariant { if typ == types.TypeVariant {
if values[ix].Type() == nil { if values[ix].Type() == nil {

View File

@@ -0,0 +1,5 @@
-- main.mcl --
import "fmt"
test fmt.printf("%d%d", 42) {} # should not pass, missing second int
-- OUTPUT --
# err: errUnify: only recursive solutions left