Skip to content

Commit

Permalink
compiler: report error instead of crashing on missing function body
Browse files Browse the repository at this point in the history
This can happen with generic functions, see:
#4486
  • Loading branch information
aykevl authored and deadprogram committed Dec 14, 2024
1 parent ec3f387 commit f246599
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
15 changes: 13 additions & 2 deletions compiler/symbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,22 +231,33 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
}
}

// Build the function if needed.
c.maybeCreateSyntheticFunction(fn, llvmFn)

return fnType, llvmFn
}

// If this is a synthetic function (such as a generic function or a wrapper),
// create it now.
func (c *compilerContext) maybeCreateSyntheticFunction(fn *ssa.Function, llvmFn llvm.Value) {
// Synthetic functions are functions that do not appear in the source code,
// they are artificially constructed. Usually they are wrapper functions
// that are not referenced anywhere except in a SSA call instruction so
// should be created right away.
// The exception is the package initializer, which does appear in the
// *ssa.Package members and so shouldn't be created here.
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
if len(fn.Blocks) == 0 {
c.addError(fn.Pos(), "missing function body")
return
}
irbuilder := c.ctx.NewBuilder()
b := newBuilder(c, irbuilder, fn)
b.createFunction()
irbuilder.Dispose()
llvmFn.SetLinkage(llvm.LinkOnceODRLinkage)
llvmFn.SetUnnamedAddr(true)
}

return fnType, llvmFn
}

// getFunctionInfo returns information about a function that is not directly
Expand Down
11 changes: 11 additions & 0 deletions testdata/errors/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ func foo() {
//go:align 7
var global int

// Test for https://github.com/tinygo-org/tinygo/issues/4486
type genericType[T any] struct{}

func (genericType[T]) methodWithoutBody()

func callMethodWithoutBody() {
msg := &genericType[int]{}
msg.methodWithoutBody()
}

// ERROR: # command-line-arguments
// ERROR: compiler.go:4:6: can only use //go:wasmimport on declarations
// ERROR: compiler.go:8:5: global variable alignment must be a positive power of two
// ERROR: compiler.go:13:23: missing function body

0 comments on commit f246599

Please sign in to comment.