diff --git a/internal/shader/expr.go b/internal/shader/expr.go index 273d4cb3e..f5a9425a7 100644 --- a/internal/shader/expr.go +++ b/internal/shader/expr.go @@ -73,6 +73,10 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar return nil, nil, nil, false } stmts = append(stmts, ss...) + if len(ts) == 0 { + cs.addError(e.Pos(), fmt.Sprintf("unexpected binary operator: %s", e.X)) + return nil, nil, nil, false + } lhst := ts[0] rhs, ts, ss, ok := cs.parseExpr(block, fname, e.Y, markLocalVariableUsed) @@ -921,7 +925,7 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar return nil, nil, nil, false } - if !isValidSwizzling(e.Sel.Name, types[0]) { + if len(types) == 0 || !isValidSwizzling(e.Sel.Name, types[0]) { cs.addError(e.Pos(), fmt.Sprintf("unexpected swizzling: %s", e.Sel.Name)) return nil, nil, nil, false } @@ -977,6 +981,10 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar cs.addError(e.Pos(), fmt.Sprintf("multiple-value context is not available at a unary operator: %s", e.X)) return nil, nil, nil, false } + if len(ts) == 0 { + cs.addError(e.Pos(), fmt.Sprintf("unexpected unary operator: %s", e.X)) + return nil, nil, nil, false + } if exprs[0].Const != nil { v := gconstant.UnaryOp(e.Op, exprs[0].Const, 0) @@ -1124,6 +1132,10 @@ func (cs *compileState) parseExpr(block *block, fname string, expr ast.Expr, mar cs.addError(e.Pos(), "multiple-value context is not available at an index expression") return nil, nil, nil, false } + if len(ts) == 0 { + cs.addError(e.Pos(), "unexpected index expression") + return nil, nil, nil, false + } x := exprs[0] t := ts[0] diff --git a/internal/shader/syntax_test.go b/internal/shader/syntax_test.go index d62cada9a..a595c0c4a 100644 --- a/internal/shader/syntax_test.go +++ b/internal/shader/syntax_test.go @@ -4061,3 +4061,51 @@ func Bar() (int, int) { t.Error("compileToIR must return an error but did not") } } + +// Issue #2926 +func TestSyntaxNonTypeExpression(t *testing.T) { + if _, err := compileToIR([]byte(`package main + +func Foo() { +} + +func Bar() float { + return +Foo +} +`)); err == nil { + t.Error("compileToIR must return an error but did not") + } + if _, err := compileToIR([]byte(`package main + +func Foo() { +} + +func Bar() float { + return Foo + 1.0 +} +`)); err == nil { + t.Error("compileToIR must return an error but did not") + } + if _, err := compileToIR([]byte(`package main + +func Foo() { +} + +func Bar() float { + return Foo.x +} +`)); err == nil { + t.Error("compileToIR must return an error but did not") + } + if _, err := compileToIR([]byte(`package main + +func Foo() { +} + +func Bar() float { + return Foo[0] +} +`)); err == nil { + t.Error("compileToIR must return an error but did not") + } +}