Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion _demo/go/export/libexport.h.want
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ GoString
TwoParams(intptr_t a, GoString b);

void
github_com_goplus_llgo__demo_go_export_init(void) GO_SYMBOL_RENAME("github.com/goplus/llgo/_demo/go/export.init")
main_init(void) GO_SYMBOL_RENAME("main.init")



Expand Down
2 changes: 1 addition & 1 deletion _demo/go/export/use/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ int main() {

// Initialize packages - call init functions first
github_com_goplus_llgo__demo_go_export_c_init();
github_com_goplus_llgo__demo_go_export_init();
main_init();

// Verify that funcinfo is not merely linkable: runtime.Callers must yield
// a symbolized frame and runtime.FuncForPC must resolve that PC's details.
Expand Down
14 changes: 14 additions & 0 deletions _demo/go/mainlink/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import _ "unsafe"

func main() {
linkdemo()
}

func demo() {
println("demo")
}

//go:linkname linkdemo main.demo
func linkdemo()
6 changes: 6 additions & 0 deletions internal/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,9 @@ func filterTestPackages(initial []*packages.Package, outFile string) ([]*package
if needLink(pkg, ModeTest) {
filtered = append(filtered, pkg)
}
if pkg.Types != nil && pkg.Types.Name() == "main" {
pkg.Types.SetName("main.test")
}
}
if len(filtered) > 1 && outFile != "" {
return nil, fmt.Errorf("cannot use -o flag with multiple packages")
Expand Down Expand Up @@ -1132,6 +1135,9 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, outputPa
methodByName := make(map[string]none)
allPkgs := []*packages.Package{pkg}
for _, v := range pkgs {
if v.PkgPath != pkg.PkgPath && v.Types.Name() == "main" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v.Types.Name() is dereferenced without a nil check, unlike the guard added a few lines up in filterTestPackages (if pkg.Types != nil && pkg.Types.Name() == "main", line 692). Elsewhere in this file p.Types is defensively nil-checked before use. A package with Types == nil (e.g. an ill-typed or synthetically-loaded dep) reaching this loop would panic. Recommend v.Types != nil && v.Types.Name() == "main" for consistency and crash-safety.

continue
}
allPkgs = append(allPkgs, v.Package)
}
visitRoots := allPkgs
Expand Down
11 changes: 9 additions & 2 deletions internal/build/main_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,15 @@ func genMainModule(ctx *context, rtPkgPath string, pkg *packages.Package, cfg *g
})
}

mainInit := declareNoArgFunc(mainPkg, pkg.PkgPath+".init")
mainMain := declareNoArgFunc(mainPkg, pkg.PkgPath+".main")
var pkgPath string
if pkg.Types.Name() == "main" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkg.Types.Name() is dereferenced without a nil guard here, whereas filterTestPackages guards the same access with pkg.Types != nil. If pkg.Types can ever be nil at this point, this panics. Add the nil check (or centralize via abi.PathOf, which already special-cases main) so the three new Name()=="main" sites behave consistently.

pkgPath = "main"
} else {
pkgPath = pkg.PkgPath
}

mainInit := declareNoArgFunc(mainPkg, pkgPath+".init")
mainMain := declareNoArgFunc(mainPkg, pkgPath+".main")

entryFn := defineEntryFunction(ctx, mainPkg, argcVar, argvVar, argvValueType, entryFunctions{
runtimeStub: runtimeStub,
Expand Down
2 changes: 1 addition & 1 deletion internal/cabi/cabi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func testModule(t *testing.T, ctx context, td llvm.TargetData, m llvm.Module, c
// check c linkname
testFunc(t, ctx, td, m.NamedFunction(fn.Name()), fn)
// check go
testFunc(t, ctx, td, m.NamedFunction("command-line-arguments."+fn.Name()), fn)
testFunc(t, ctx, td, m.NamedFunction("main."+fn.Name()), fn)
}
}

Expand Down
3 changes: 3 additions & 0 deletions ssa/abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ func PathOf(pkg *types.Package) string {
if pkg == nil {
return ""
}
if pkg.Name() == "main" {
return "main"
}
return strings.TrimPrefix(pkg.Path(), PatchPathPrefix)
}

Expand Down
2 changes: 1 addition & 1 deletion ssa/abitype.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ func methodExprSignature(sig *types.Signature) *types.Signature {
func (b Builder) abiMethodFunc(anonymous bool, mPkg *types.Package, mName string, mSig *types.Signature) Function {
var fullName string
if anonymous {
fullName = b.Pkg.Path() + "." + mSig.Recv().Type().String() + "." + mName
fullName = b.Pkg.Path() + "." + types.TypeString(mSig.Recv().Type(), abi.PathOf) + "." + mName
} else {
fullName = FuncName(mPkg, mName, mSig.Recv(), false)
}
Expand Down
Loading