Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gccgo: incorrectly imported call/deref sequence in inlinable function #34503

Closed
thanm opened this issue Sep 24, 2019 · 2 comments
Closed

gccgo: incorrectly imported call/deref sequence in inlinable function #34503

thanm opened this issue Sep 24, 2019 · 2 comments
Milestone

Comments

@thanm
Copy link
Contributor

thanm commented Sep 24, 2019

What version of Go are you using (go version)?

gccgo tip

$ go version
go version go1.13 gccgo (GCC) 10.0.0 20190916 (experimental) linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

Compile these two packages:

Package "b":

package b

import (
	"sync/atomic"
	"unsafe"
)

type HookFunc func(x uint64)

var HookV unsafe.Pointer

func Hook(x uint64) {
	if hkf := atomic.LoadPointer(&HookV); hkf != nil {
		(*(*HookFunc)(hkf))(x)
	}
}

Package "c":

package c

import "b"

func Cfunc() {
	b.Hook(101)
}

Then build first b and then c.

What did you expect to see?

clean compile

What did you see instead?

$ go build c
 /src/b/b.go:18: error: expected function
 /src/b/b.go:18: error: expected pointer
$

I spent a little while poking at this and I believe that the problem is with the exporter/importer for inlinable function bodies. Here's what the inlinable function "Hook" looks like in the export data:

func Hook (x ) 
// /ssd2/go1/src/b/b.go:16
{ //17
var hkf  = LoadPointer(&HookV) //17
if (hkf != $nil) { //17
*$convert(, hkf)(x) //18
} //17
} //19

For the expression on line 18, when compiling the original code in package "b", the IR looks like

call(fn=deref(convert(var(hkf))), val=var(x))

or from the debugger:

(gdb) p debug_go_statement(this)
*((hkf) (x) ) // b.go:18

whereas when trying to lower the inlined copy of the routine while compiling package "c", we get:

deref(call(fn=convert(var(hkf)), val=var(x)))

or from the debugger:

(gdb) p debug_go_statement(this)
*((hkf) ) (x) // b.go:18

Off the top of my head I would guess that this is a precedence problem in the importer's parser. I'll look into a fix of some sort.

@thanm thanm added this to the Gccgo milestone Sep 24, 2019
@thanm thanm self-assigned this Sep 24, 2019
@gopherbot
Copy link

Change https://golang.org/cl/197122 mentions this issue: compiler: resolve importing ambiguity for more complex function calls

@gopherbot
Copy link

Change https://golang.org/cl/197217 mentions this issue: test: add testcase for gccgo compiler buglet

gopherbot pushed a commit that referenced this issue Sep 25, 2019
New test containing code that caused a gccgo compiler failure.

Updates #34503.

Change-Id: Id895a1e1249062b7fb147e54bcaa657e774ed0d9
Reviewed-on: https://go-review.googlesource.com/c/go/+/197217
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
jpf91 pushed a commit to D-Programming-GDC/gcc that referenced this issue Sep 28, 2019
    
    Tweak the exporter for inlinable function bodies to work around a
    problem with importing of function calls whose function expressions
    are not simple function names. In the bug in question, the function
    body exporter was writing out a function call of the form
    
           (*(*FuncTyp)(var))(arg)
    
    which produced an export data representation of
    
           *$convert(<type 5>, var)(x)
    
    which is hard to parse unambiguously. Fix: change the export data
    emitter to introduce parens around the function expression for more
    complex calls.
    
    Testcase for this bug is in CL 197217.
    
    Fixes golang/go#34503.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/197122


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@276228 138bc75d-0d04-0410-961f-82ee72b054a4
@golang golang locked and limited conversation to collaborators Sep 27, 2020
asiekierka pushed a commit to WonderfulToolchain/gcc-ia16 that referenced this issue May 16, 2022
    
    Tweak the exporter for inlinable function bodies to work around a
    problem with importing of function calls whose function expressions
    are not simple function names. In the bug in question, the function
    body exporter was writing out a function call of the form
    
           (*(*FuncTyp)(var))(arg)
    
    which produced an export data representation of
    
           *$convert(<type 5>, var)(x)
    
    which is hard to parse unambiguously. Fix: change the export data
    emitter to introduce parens around the function expression for more
    complex calls.
    
    Testcase for this bug is in CL 197217.
    
    Fixes golang/go#34503.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/197122

From-SVN: r276228
@rsc rsc unassigned thanm Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants