internal/shader: Bug fix: Error on duplicated const/var names

Updates #1192
This commit is contained in:
Hajime Hoshi 2021-04-09 00:12:14 +09:00
parent 59a80cf953
commit 3b6fa891ac
2 changed files with 81 additions and 2 deletions

View File

@ -540,6 +540,12 @@ func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) ([]variabl
return nil, nil, nil, false return nil, nil, nil, false
} }
} }
for _, c := range block.consts {
if c.name == name {
s.addError(vs.Pos(), fmt.Sprintf("duplicated local constant/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,
@ -561,12 +567,26 @@ func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) ([]constan
var cs []constant var cs []constant
for i, n := range vs.Names { for i, n := range vs.Names {
name := n.Name
for _, c := range block.consts {
if c.name == name {
s.addError(vs.Pos(), fmt.Sprintf("duplicated local constant name: %s", name))
return nil, false
}
}
for _, v := range block.vars {
if v.name == name {
s.addError(vs.Pos(), fmt.Sprintf("duplicated local constant/variable name: %s", name))
return nil, false
}
}
es, _, ss, ok := s.parseExpr(block, vs.Values[i], false) es, _, ss, ok := s.parseExpr(block, vs.Values[i], false)
if !ok { if !ok {
return nil, false return nil, false
} }
if len(ss) > 0 { if len(ss) > 0 {
s.addError(vs.Pos(), fmt.Sprintf("invalid constant expression: %s", n)) s.addError(vs.Pos(), fmt.Sprintf("invalid constant expression: %s", name))
return nil, false return nil, false
} }
if len(es) != 1 { if len(es) != 1 {
@ -578,7 +598,7 @@ func (s *compileState) parseConstant(block *block, vs *ast.ValueSpec) ([]constan
return nil, false return nil, false
} }
cs = append(cs, constant{ cs = append(cs, constant{
name: n.Name, name: name,
typ: t, typ: t,
value: es[0].Const, value: es[0].Const,
}) })

View File

@ -780,6 +780,65 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
} }
} }
func TestShaderDuplicatedVarsAndConstants(t *testing.T) {
if _, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
var a = 0
const a = 0
return vec4(a)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
if _, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
const a = 0
var a = 0
return vec4(a)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
if _, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
const a = 0
const a = 0
return vec4(a)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
if _, err := NewShader([]byte(`package main
const U0 = 0
var U0 float
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return vec4(a)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
if _, err := NewShader([]byte(`package main
var U0 float
const U0 = 0
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return vec4(a)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
}
func TestShaderMatrix(t *testing.T) { func TestShaderMatrix(t *testing.T) {
const w, h = 16, 16 const w, h = 16, 16