aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2023-03-24 00:23:03 +0100
committerRon Evans <[email protected]>2024-09-23 09:41:44 +0100
commit37460ad60af2601a0412426c229663443c8d8eaa (patch)
tree0800550e161710c78f91fd8ffc5ef63aec60f59d /compiler
parentdcca47f1f6088ea2565468e4a93a96e4308af480 (diff)
downloadtinygo-37460ad60af2601a0412426c229663443c8d8eaa.tar.gz
tinygo-37460ad60af2601a0412426c229663443c8d8eaa.zip
compiler: support pragmas on generic functions
Diffstat (limited to 'compiler')
-rw-r--r--compiler/symbol.go8
-rw-r--r--compiler/testdata/pragma.go16
-rw-r--r--compiler/testdata/pragma.ll13
3 files changed, 35 insertions, 2 deletions
diff --git a/compiler/symbol.go b/compiler/symbol.go
index 29f009520..32eb55107 100644
--- a/compiler/symbol.go
+++ b/compiler/symbol.go
@@ -250,10 +250,14 @@ func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
// parsePragmas is used by getFunctionInfo to parse function pragmas such as
// //export or //go:noinline.
func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
- if f.Syntax() == nil {
+ syntax := f.Syntax()
+ if f.Origin() != nil {
+ syntax = f.Origin().Syntax()
+ }
+ if syntax == nil {
return
}
- if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil {
+ if decl, ok := syntax.(*ast.FuncDecl); ok && decl.Doc != nil {
for _, comment := range decl.Doc.List {
text := comment.Text
if strings.HasPrefix(text, "//export ") {
diff --git a/compiler/testdata/pragma.go b/compiler/testdata/pragma.go
index fa1d4b0e9..1f6badf7f 100644
--- a/compiler/testdata/pragma.go
+++ b/compiler/testdata/pragma.go
@@ -48,6 +48,22 @@ func inlineFunc() {
func noinlineFunc() {
}
+type Int interface {
+ int8 | int16
+}
+
+// Same for generic functions (but the compiler may miss the pragma due to it
+// being generic).
+//
+//go:noinline
+func noinlineGenericFunc[T Int]() {
+}
+
+func useGeneric() {
+ // Make sure the generic function above is instantiated.
+ noinlineGenericFunc[int8]()
+}
+
// This function should have the specified section.
//
//go:section .special_function_section
diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll
index 3ee4078f1..28e678359 100644
--- a/compiler/testdata/pragma.ll
+++ b/compiler/testdata/pragma.ll
@@ -48,6 +48,19 @@ entry:
ret void
}
+; Function Attrs: nounwind
+define hidden void @main.useGeneric(ptr %context) unnamed_addr #2 {
+entry:
+ call void @"main.noinlineGenericFunc[int8]"(ptr undef)
+ ret void
+}
+
+; Function Attrs: noinline nounwind
+define linkonce_odr hidden void @"main.noinlineGenericFunc[int8]"(ptr %context) unnamed_addr #5 {
+entry:
+ ret void
+}
+
; Function Attrs: noinline nounwind
define hidden void @main.functionInSection(ptr %context) unnamed_addr #5 section ".special_function_section" {
entry: