shader: Friendly error messages when local variable names are duplicated

Fixes #1254
This commit is contained in:
Hajime Hoshi 2020-08-30 21:11:27 +09:00
parent 349faa0f34
commit 8c779447db
3 changed files with 87 additions and 2 deletions

View File

@ -483,6 +483,12 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
} }
name := n.Name name := n.Name
for _, v := range append(block.vars, vars...) {
if v.name == name {
s.addError(vs.Pos(), fmt.Sprintf("duplicated local variable name: %s", name))
return nil, nil, nil, false
}
}
vars = append(vars, variable{ vars = append(vars, variable{
name: name, name: name,
typ: t, typ: t,

View File

@ -455,8 +455,15 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
stmts = append(stmts, ss...) stmts = append(stmts, ss...)
if define { if define {
name := e.(*ast.Ident).Name
for _, v := range block.vars {
if v.name == name {
cs.addError(pos, fmt.Sprintf("duplicated local variable name: %s", name))
return nil, false
}
}
v := variable{ v := variable{
name: e.(*ast.Ident).Name, name: name,
} }
ts, ok := cs.functionReturnTypes(block, rhs[i]) ts, ok := cs.functionReturnTypes(block, rhs[i])
if !ok { if !ok {
@ -545,8 +552,15 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
} }
if define { if define {
name := e.(*ast.Ident).Name
for _, v := range block.vars {
if v.name == name {
cs.addError(pos, fmt.Sprintf("duplicated local variable name: %s", name))
return nil, false
}
}
v := variable{ v := variable{
name: e.(*ast.Ident).Name, name: name,
} }
v.typ = rhsTypes[i] v.typ = rhsTypes[i]
block.vars = append(block.vars, v) block.vars = append(block.vars, v)

View File

@ -114,3 +114,68 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
} }
} }
} }
func TestShaderShadowing(t *testing.T) {
_, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
var position vec4
return position
}
`))
if err == nil {
t.Errorf("error must be non-nil but was nil")
}
}
func TestShaderDuplicatedVariables(t *testing.T) {
_, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
var foo vec4
var foo vec4
return foo
}
`))
if err == nil {
t.Errorf("error must be non-nil but was nil")
}
_, err = NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
var foo, foo vec4
return foo
}
`))
if err == nil {
t.Errorf("error must be non-nil but was nil")
}
_, err = NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
var foo vec4
foo := vec4(0)
return foo
}
`))
if err == nil {
t.Errorf("error must be non-nil but was nil")
}
_, err = NewShader([]byte(`package main
func Foo() (vec4, vec4) {
return vec4(0), vec4(0)
}
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
foo, foo := Foo()
return foo
}
`))
if err == nil {
t.Errorf("error must be non-nil but was nil")
}
}