@@ -1662,7 +1662,7 @@ func (p *parser) forStmt() Stmt {
1662
1662
s .init (p )
1663
1663
1664
1664
p .want (_For )
1665
- s .Init , s .Cond , s .Post = p .header (true )
1665
+ s .Init , s .Cond , s .Post = p .header (_For )
1666
1666
if gcCompat {
1667
1667
s .init (p )
1668
1668
}
@@ -1688,10 +1688,13 @@ func (p *parser) stmtBody(context string) []Stmt {
1688
1688
return body
1689
1689
}
1690
1690
1691
- var dummyCond = & Name {Value : "false" }
1691
+ func (p * parser ) header (keyword token ) (init SimpleStmt , cond Expr , post SimpleStmt ) {
1692
+ // TODO(gri) move caller's p.want(keyword) here, once we removed gcCompat
1692
1693
1693
- func (p * parser ) header (forStmt bool ) (init SimpleStmt , cond Expr , post SimpleStmt ) {
1694
1694
if p .tok == _Lbrace {
1695
+ if keyword == _If {
1696
+ p .syntax_error ("missing condition in if statement" )
1697
+ }
1695
1698
return
1696
1699
}
1697
1700
@@ -1700,20 +1703,27 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
1700
1703
1701
1704
if p .tok != _Semi {
1702
1705
// accept potential varDecl but complain
1703
- if forStmt && p .got (_Var ) {
1706
+ if keyword == _For && p .got (_Var ) {
1704
1707
p .syntax_error ("var declaration not allowed in for initializer" )
1705
1708
}
1706
- init = p .simpleStmt (nil , forStmt )
1707
- // If we have a range clause, we are done.
1709
+ init = p .simpleStmt (nil , keyword == _For )
1710
+ // If we have a range clause, we are done (can only happen for keyword == _For) .
1708
1711
if _ , ok := init .(* RangeClause ); ok {
1709
1712
p .xnest = outer
1710
1713
return
1711
1714
}
1712
1715
}
1713
1716
1714
1717
var condStmt SimpleStmt
1715
- if p .got (_Semi ) {
1716
- if forStmt {
1718
+ var semi struct {
1719
+ pos src.Pos
1720
+ lit string
1721
+ }
1722
+ if p .tok == _Semi {
1723
+ semi .pos = p .pos ()
1724
+ semi .lit = p .lit
1725
+ p .next ()
1726
+ if keyword == _For {
1717
1727
if p .tok != _Semi {
1718
1728
condStmt = p .simpleStmt (nil , false )
1719
1729
}
@@ -1732,12 +1742,17 @@ func (p *parser) header(forStmt bool) (init SimpleStmt, cond Expr, post SimpleSt
1732
1742
// unpack condStmt
1733
1743
switch s := condStmt .(type ) {
1734
1744
case nil :
1735
- // nothing to do
1745
+ if keyword == _If {
1746
+ if semi .lit != "semicolon" {
1747
+ p .syntax_error_at (semi .pos , fmt .Sprintf ("unexpected %s, expecting { after if clause" , semi .lit ))
1748
+ } else {
1749
+ p .syntax_error_at (semi .pos , "missing condition in if statement" )
1750
+ }
1751
+ }
1736
1752
case * ExprStmt :
1737
1753
cond = s .X
1738
1754
default :
1739
1755
p .syntax_error (fmt .Sprintf ("%s used as value" , String (s )))
1740
- cond = dummyCond // avoid follow-up error for if statements
1741
1756
}
1742
1757
1743
1758
p .xnest = outer
@@ -1753,10 +1768,7 @@ func (p *parser) ifStmt() *IfStmt {
1753
1768
s .init (p )
1754
1769
1755
1770
p .want (_If )
1756
- s .Init , s .Cond , _ = p .header (false )
1757
- if s .Cond == nil {
1758
- p .syntax_error ("missing condition in if statement" )
1759
- }
1771
+ s .Init , s .Cond , _ = p .header (_If )
1760
1772
1761
1773
if gcCompat {
1762
1774
s .init (p )
@@ -1788,7 +1800,7 @@ func (p *parser) switchStmt() *SwitchStmt {
1788
1800
s := new (SwitchStmt )
1789
1801
s .init (p )
1790
1802
1791
- s .Init , s .Tag , _ = p .header (false )
1803
+ s .Init , s .Tag , _ = p .header (_Switch )
1792
1804
1793
1805
if ! p .got (_Lbrace ) {
1794
1806
p .syntax_error ("missing { after switch clause" )
0 commit comments