Repository: burrowers/garble (go)

Issue:
Unsafe package with Control flow
<!--
Please answer these questions before submitting your issue. Thanks!
-->

### What version of Garble and Go are you using?
1.23.3

<pre>
$ garble version
mvdan.cc/garble v0.13.0
$ go version
go version go1.23.3 windows/amd64

</pre>

### What environment are you running Garble on?
Windows 11

<!--
Please run "go env" in the same directory where you run garble.
-->

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\GUY\AppData\Local\go-build
set GOENV=C:\Users\GUY\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\GUY\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\GUY\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.23.3
set GODEBUG=
set GOTELEMETRY=local
set GOTELEMETRYDIR=C:\Users\GUY\AppData\Roaming\go\telemetry
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\GUY\AppData\Local\Temp\go-build1744563614=/tmp/go-build -gno-record-gcc-switches

</pre></details>

### What did you do?
create a main.go with a package using unsafe package and 
use //garble:controlflow
<!--
Provide clear steps for others to reproduce the error.
If your code is private, try reproducing via a small program.
As a fallback, provide as many relevant details as possible.
-->
1. Create a main.go which call a package
2. the package need to use unsafe package and //garble:controlflow on it
3. it will simply crash saying it cannot resolve the package  or typecheck error: utils\unsafe.go:5:2: "unsafe" imported and not used



### What did you expect to see?
Compile it normally

### What did you see instead?
Crashing



Pull request:
fixes #903

Patch:
diff --git a/main.go b/main.go
index 1b8143a..998664e 100644
--- a/main.go
+++ b/main.go
@@ -1248,6 +1248,11 @@ func (tf *transformer) processImportCfg(flags []string, requiredPkgs []string) (
 	if requiredPkgs != nil {
 		newIndirectImports = make(map[string]bool)
 		for _, pkg := range requiredPkgs {
+			// unsafe is a special case, it's not a real dependency
+			if pkg == "unsafe" {
+				continue
+			}
+
 			newIndirectImports[pkg] = true
 		}
 	}
@@ -1727,6 +1732,8 @@ func recordType(used, origin types.Type, done map[*types.Named]bool, fieldToStru
 // Unsafe types: generic types and non-method interfaces.
 func isSafeForInstanceType(t types.Type) bool {
 	switch t := types.Unalias(t).(type) {
+	case *types.Basic:
+		return t.Kind() != types.Invalid
 	case *types.Named:
 		if t.TypeParams().Len() > 0 {
 			return false


Test patch:
diff --git a/testdata/script/ctrlflow.txtar b/testdata/script/ctrlflow.txtar
index 57800d6..ed31589 100644
--- a/testdata/script/ctrlflow.txtar
+++ b/testdata/script/ctrlflow.txtar
@@ -38,6 +38,7 @@ import (
 	"encoding/binary"
 	"encoding/hex"
 	"hash/crc32"
+	"unsafe"
 )
 
 //garble:controlflow flatten_passes=0 junk_jumps=max block_splits=max
@@ -78,6 +79,22 @@ func multiHardeningTest(i int) int {
     return multiply(i);
 }
 
+//garble:controlflow
+func ModifyValue() {
+	var a int = 42
+	var p *int = &a
+
+	println("Value of a:", a)
+
+	var up unsafe.Pointer = unsafe.Pointer(p)
+
+	var p2 *int = (*int)(up)
+
+	*p2 = 100
+
+	println("New value of a:", a)
+}
+
 //garble:controlflow flatten_passes=1 junk_jumps=10 block_splits=10 trash_blocks=32
 func main() {
 	// Reference to the unexported interface triggers creation of a new interface
@@ -106,6 +123,7 @@ func main() {
 	println(xorHardeningTest(0))
 	println(delegateHardeningTest(0))
 	println(multiHardeningTest(0))
+	ModifyValue()
 }
 
 -- main.stderr --
@@ -116,4 +134,6 @@ correct name
 884863d2
 1
 1
-1
\ No newline at end of file
+1
+Value of a: 42
+New value of a: 100