shader: Bug fix: a blank identifier cannot be used as values

This commit is contained in:
Hajime Hoshi 2020-09-13 23:48:12 +09:00
parent 6114c2b49d
commit 7666987b09
3 changed files with 55 additions and 6 deletions

View File

@ -370,11 +370,17 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr, markLocalVariable
case *ast.Ident:
if e.Name == "_" {
// In the context where a local variable is marked as used, any expressions must have its
// meaning. Then, a blank identifier is not available there.
if markLocalVariableUsed {
cs.addError(e.Pos(), fmt.Sprintf("cannot use _ as value"))
return nil, nil, nil, false
}
return []shaderir.Expr{
{
Type: shaderir.Blank,
},
}, nil, nil, true
}, []shaderir.Type{{}}, nil, true
}
if i, t, ok := block.findLocalVariable(e.Name, markLocalVariableUsed); ok {
return []shaderir.Expr{

View File

@ -520,11 +520,7 @@ func (cs *compileState) assign(block *block, fname string, pos token.Pos, lhs, r
return nil, false
}
var t shaderir.Type
if len(ts) == 1 {
t = ts[0]
}
block.addNamedLocalVariable(name, t, e.Pos())
block.addNamedLocalVariable(name, ts[0], e.Pos())
}
if len(r) > 1 {

View File

@ -563,3 +563,50 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
t.Errorf("error must be non-nil but was nil")
}
}
func TestShaderBlankRhs(t *testing.T) {
if _, err := NewShader([]byte(`package main
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
x := _
_ = x
return vec4(0)
}
`)); 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 {
var x int = _
_ = x
return vec4(0)
}
`)); 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 {
x := 1
x = _
_ = x
return vec4(0)
}
`)); 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 {
x := 1 + _
_ = x
return vec4(0)
}
`)); err == nil {
t.Errorf("error must be non-nil but was nil")
}
}