I have been using the cfg package to create cfg of go programs. While working with SelectStmt, I’ve found the cfg a bit odd. For example:
func Foo() bool {
var c1, c2 chan int
select {
case c1 <- 1:
fmt.Print("c1 <- 1")
case c1 <- 3:
fmt.Print("c1 <- 3")
case <-c2:
default:
fmt.Print("default")
}
return true
}
For this code snippet, CFG is generated like below:
.0: # entry
c1, c2 chan int
c1 ← 1
c1 ← 3
<-c2
succs: 2 3
.1: # select.done
return true
.2: # select.body
fmt.Print(“c1 ← 1”)
succs: 1
.3: # select.next
succs: 4 5
.4: # select.body
fmt.Print(“c1 ← 3”)
succs: 1
.5: # select.next
succs: 6 7
.6: # select.body
succs: 1
.7: # select.next
fmt.Print(“default”)
succs: 1
.8: # unreachable.return
Here in block 0, We can find all the Comms are present sequentially, suggesting CommClauses are evaluated sequentially which is similar to switch. I was expecting something like the following. There should be multiple paths from block 0 (instead of true,false path):
.0: # entry
msg []string
c1, c2 chan int
succs: 1, 2, 3, 4
.1 # select.body
c1 ← 1
fmt.Print(“c1 ← 1”)
succs : 5
.2 # select.body
c3 ← 1
fmt.Print(“c1 ← 3”)
succs : 5
.3 # select.body
← c2
succs : 5
.4 # select.body
fmt.Print(“default”)
succs : 5
.5 # select.done
return true
Am I missing Something?