Skip to content

Commit 8443c57

Browse files
committed
Merge branch 'new' into go-1.26
2 parents 3463204 + b593145 commit 8443c57

File tree

2 files changed

+115
-6
lines changed

2 files changed

+115
-6
lines changed

testdata/examples/channel/channel.gold.v

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ Definition select_nb_no_panic {ext : ffi_syntax} {go_gctx : GoGlobalContext} : g
6060

6161
Definition select_no_double_close {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.select_no_double_close"%go.
6262

63+
Definition select_nb_full_buffer_no_panic {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.select_nb_full_buffer_no_panic"%go.
64+
65+
Definition select_nb_buffer_space_panic {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.select_nb_buffer_space_panic"%go.
66+
67+
Definition select_nb_buffer_space_deadlock {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.select_nb_buffer_space_deadlock"%go.
68+
6369
Definition exchangePointer {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.exchangePointer"%go.
6470

6571
Definition BroadcastExample {ext : ffi_syntax} {go_gctx : GoGlobalContext} : go_string := "github.com/goose-lang/goose/testdata/examples/channel.BroadcastExample"%go.
@@ -542,7 +548,56 @@ Definition select_no_double_closeⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlo
542548
(FuncResolve go.close [go.ChannelType go.sendrecv go.int] #()) "$a0"))) [(CommClause (RecvCase go.int "$ch0") (do: #()))]);;;
543549
return: #()).
544550

545-
(* go: examples.go:148:6 *)
551+
(* Show that a nonblocking select does not take a send case
552+
when the buffered channel is already full.
553+
554+
go: examples.go:150:6 *)
555+
Definition select_nb_full_buffer_no_panicⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
556+
λ: <>,
557+
exception_do (let: "ch" := (GoAlloc (go.ChannelType go.sendrecv go.int) (GoZeroVal (go.ChannelType go.sendrecv go.int) #())) in
558+
let: "$r0" := ((FuncResolve go.make2 [go.ChannelType go.sendrecv go.int] #()) #(W64 1)) in
559+
do: ("ch" <-[go.ChannelType go.sendrecv go.int] "$r0");;;
560+
do: (let: "$chan" := (![go.ChannelType go.sendrecv go.int] "ch") in
561+
let: "$v" := #(W64 0) in
562+
chan.send go.int "$chan" "$v");;;
563+
let: "$v0" := #(W64 0) in
564+
let: "$ch0" := (![go.ChannelType go.sendrecv go.int] "ch") in
565+
SelectStmt (SelectStmtClauses (Some (do: #())) [(CommClause (SendCase go.int "$ch0" "$v0") (do: (let: "$a0" := (Convert go.string (go.InterfaceType []) #"unreachable"%go) in
566+
(FuncResolve go.panic [] #()) "$a0")))]);;;
567+
return: #()).
568+
569+
(* Unverifiable: Panic is irreducible
570+
571+
go: examples.go:169:6 *)
572+
Definition select_nb_buffer_space_panicⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
573+
λ: <>,
574+
exception_do (let: "ch" := (GoAlloc (go.ChannelType go.sendrecv go.int) (GoZeroVal (go.ChannelType go.sendrecv go.int) #())) in
575+
let: "$r0" := ((FuncResolve go.make2 [go.ChannelType go.sendrecv go.int] #()) #(W64 1)) in
576+
do: ("ch" <-[go.ChannelType go.sendrecv go.int] "$r0");;;
577+
let: "$v0" := #(W64 0) in
578+
let: "$ch0" := (![go.ChannelType go.sendrecv go.int] "ch") in
579+
SelectStmt (SelectStmtClauses (Some (do: #())) [(CommClause (SendCase go.int "$ch0" "$v0") (do: (let: "$a0" := (Convert go.string (go.InterfaceType []) #"bad"%go) in
580+
(FuncResolve go.panic [] #()) "$a0")))]);;;
581+
return: #()).
582+
583+
(* Blocking select: vacuously verifiable due to deadlock
584+
585+
go: examples.go:184:6 *)
586+
Definition select_nb_buffer_space_deadlockⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
587+
λ: <>,
588+
exception_do (let: "ch" := (GoAlloc (go.ChannelType go.sendrecv go.int) (GoZeroVal (go.ChannelType go.sendrecv go.int) #())) in
589+
let: "$r0" := ((FuncResolve go.make2 [go.ChannelType go.sendrecv go.int] #()) #(W64 1)) in
590+
do: ("ch" <-[go.ChannelType go.sendrecv go.int] "$r0");;;
591+
do: (let: "$chan" := (![go.ChannelType go.sendrecv go.int] "ch") in
592+
let: "$v" := #(W64 0) in
593+
chan.send go.int "$chan" "$v");;;
594+
let: "$v0" := #(W64 0) in
595+
let: "$ch0" := (![go.ChannelType go.sendrecv go.int] "ch") in
596+
SelectStmt (SelectStmtClauses None [(CommClause (SendCase go.int "$ch0" "$v0") (do: (let: "$a0" := (Convert go.string (go.InterfaceType []) #"unreachable"%go) in
597+
(FuncResolve go.panic [] #()) "$a0")))]);;;
598+
return: #()).
599+
600+
(* go: examples.go:199:6 *)
546601
Definition exchangePointerⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
547602
λ: <>,
548603
exception_do (let: "x" := (GoAlloc go.int (GoZeroVal go.int #())) in
@@ -596,7 +651,7 @@ Definition exchangePointerⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalCont
596651
else do: #());;;
597652
return: #()).
598653

599-
(* go: examples.go:168:6 *)
654+
(* go: examples.go:219:6 *)
600655
Definition BroadcastExampleⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
601656
λ: <>,
602657
exception_do (let: "done" := (GoAlloc (go.ChannelType go.sendrecv (go.StructType [
@@ -673,27 +728,27 @@ Definition BroadcastExampleⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalCon
673728
else do: #());;;
674729
return: #()).
675730

676-
(* go: examples.go:204:6 *)
731+
(* go: examples.go:255:6 *)
677732
Definition Webⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
678733
λ: "query",
679734
exception_do (let: "query" := (GoAlloc go.string "query") in
680735
return: ((![go.string] "query") +⟨go.string⟩ #".html"%go)).
681736

682-
(* go: examples.go:208:6 *)
737+
(* go: examples.go:259:6 *)
683738
Definition Imageⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
684739
λ: "query",
685740
exception_do (let: "query" := (GoAlloc go.string "query") in
686741
return: ((![go.string] "query") +⟨go.string⟩ #".png"%go)).
687742

688-
(* go: examples.go:212:6 *)
743+
(* go: examples.go:263:6 *)
689744
Definition Videoⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
690745
λ: "query",
691746
exception_do (let: "query" := (GoAlloc go.string "query") in
692747
return: ((![go.string] "query") +⟨go.string⟩ #".mp4"%go)).
693748

694749
(* https://go.dev/talks/2012/concurrency.slide#46
695750
696-
go: examples.go:217:6 *)
751+
go: examples.go:268:6 *)
697752
Definition Googleⁱᵐᵖˡ {ext : ffi_syntax} {go_gctx : GoGlobalContext} : val :=
698753
λ: "query",
699754
exception_do (let: "query" := (GoAlloc go.string "query") in
@@ -1629,6 +1684,9 @@ Class Assumptions {ext : ffi_syntax} `{!GoGlobalContext} `{!GoLocalContext} `{!G
16291684
#[global] simple_multi_join_unfold :: FuncUnfold simple_multi_join [] (simple_multi_joinⁱᵐᵖˡ);
16301685
#[global] select_nb_no_panic_unfold :: FuncUnfold select_nb_no_panic [] (select_nb_no_panicⁱᵐᵖˡ);
16311686
#[global] select_no_double_close_unfold :: FuncUnfold select_no_double_close [] (select_no_double_closeⁱᵐᵖˡ);
1687+
#[global] select_nb_full_buffer_no_panic_unfold :: FuncUnfold select_nb_full_buffer_no_panic [] (select_nb_full_buffer_no_panicⁱᵐᵖˡ);
1688+
#[global] select_nb_buffer_space_panic_unfold :: FuncUnfold select_nb_buffer_space_panic [] (select_nb_buffer_space_panicⁱᵐᵖˡ);
1689+
#[global] select_nb_buffer_space_deadlock_unfold :: FuncUnfold select_nb_buffer_space_deadlock [] (select_nb_buffer_space_deadlockⁱᵐᵖˡ);
16321690
#[global] exchangePointer_unfold :: FuncUnfold exchangePointer [] (exchangePointerⁱᵐᵖˡ);
16331691
#[global] BroadcastExample_unfold :: FuncUnfold BroadcastExample [] (BroadcastExampleⁱᵐᵖˡ);
16341692
#[global] Web_unfold :: FuncUnfold Web [] (Webⁱᵐᵖˡ);

testdata/examples/channel/examples.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,57 @@ func select_no_double_close() {
145145
}
146146
}
147147

148+
// Show that a nonblocking select does not take a send case
149+
// when the buffered channel is already full.
150+
func select_nb_full_buffer_no_panic() {
151+
// 1. Buffered channel of size 1
152+
ch := make(chan int, 1)
153+
154+
// 2. Fill the buffer
155+
ch <- 0
156+
157+
// 3. Nonblocking select:
158+
// the send case would panic,
159+
// so it must NOT be taken.
160+
select {
161+
case ch <- 0:
162+
panic("unreachable")
163+
default:
164+
// benign: correct behavior
165+
}
166+
}
167+
168+
// Unverifiable: Panic is irreducible
169+
func select_nb_buffer_space_panic() {
170+
// Create a buffered channel with capacity 1
171+
ch := make(chan int, 1)
172+
173+
// Nonblocking select:
174+
// the send case is enabled and may be chosen.
175+
select {
176+
case ch <- 0:
177+
// This panic is reachable
178+
panic("bad")
179+
default:
180+
}
181+
}
182+
183+
// Blocking select: vacuously verifiable due to deadlock
184+
func select_nb_buffer_space_deadlock() {
185+
// Create a buffered channel with capacity 1
186+
ch := make(chan int, 1)
187+
188+
// First send fills the buffer
189+
ch <- 0
190+
191+
// Blocks indefinitely on send.
192+
select {
193+
case ch <- 0:
194+
// This code is unreachable
195+
panic("unreachable")
196+
}
197+
}
198+
148199
func exchangePointer() {
149200
x := 0
150201
y := 0

0 commit comments

Comments
 (0)