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

cmd/cgo: compiler accepts invalid declaration of methods on aliases to C types #60725

Closed
eliasnaur opened this issue Jun 11, 2023 · 22 comments
Closed
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FixPending Issues that have a fix which has not yet been reviewed or submitted.
Milestone

Comments

@eliasnaur
Copy link
Contributor

eliasnaur commented Jun 11, 2023

This program successfully runs with Go 1.21:

$ cat cgo_methods.go
package main

/*
typedef int foo;
*/
import "C"

type foo = C.foo

func (foo) method() int { return 123 }

func main() {
	var x foo
	println(x.method()) // "123"
}
$ go run cgo_methods.go
123

I believe this program is invalid for the same reason as the program in #57926. Note that in contrast to that issue, this program uses an alias to define a method on a C type.

@ianlancetaylor
Copy link
Member

@alandonovan pointed out this hole in the current cgo detection of methods on C types, and I said it didn't seem worth worrying about, because who would put a method on a type alias? Interesting to see that people actually do this.

If anybody sees a simple way to fix this, by all means go for it.

@ianlancetaylor ianlancetaylor added this to the Backlog milestone Jun 11, 2023
@ianlancetaylor ianlancetaylor added the NeedsFix The path to resolution is known, but the work has not been done. label Jun 11, 2023
@adonovan
Copy link
Member

adonovan commented Jun 12, 2023

Clearly the fix has to be done in the compiler (since it requires symbol resolution), which I think means it will generally be possible to hand-craft some valid Go source file that that spuriously triggers the error (since cgo-generated source has no special privilege). I think this means that any approach is going to be at best a heuristic and that false positives are possible. That said, false positives (artificially weird code that doesn't compile when it should) seem less important than false negatives (such as this issue).

Some clues we could use for a heuristic:

  • the receiver type name is of the form _C_foo.
  • the file name is of the form go-build/XX/X{64}-d.
  • the file contains a Code generated by cmd/cgo comment.
  • the file uses //line directives.
  • the file blank-imports the unsafe package.

Some combination of these, plus a test that the error is positively produced, is probably good enough.

@ianlancetaylor
Copy link
Member

Just a note that I don't think we really need a heuristic to detect cgo-generated code. The cmd/go tool knows when it is compiling a Go file generated by cmd/cgo, and it could pass a special option to cmd/compile indicating that. Of course other people could use -gcflags to pass the same option....

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/503395 mentions this issue: cmd/cgo: compiler accepts invalid declaration of methods on aliases to C types

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/503397 mentions this issue: cmd/go: compiler accepts invalid declaration of methods on aliases to C types

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/503396 mentions this issue: cmd/compile: compiler accepts invalid declaration of methods on aliases to C types

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/503596 mentions this issue: go/types,types: compiler should not accept invalid declaration of methods on aliases to C types

@cuiweixie
Copy link
Contributor

Change https://go.dev/cl/503596 mentions this issue: go/types,types: compiler should not accept invalid declaration of methods on aliases to C types

this fix is simple enough. Is it ok? @ianlancetaylor

@cuiweixie
Copy link
Contributor

@alandonovan pointed out this hole in the current cgo detection of methods on C types, and I said it didn't seem worth worrying about, because who would put a method on a type alias? Interesting to see that people actually do this.

If anybody sees a simple way to fix this, by all means go for it.

I think this condition is simple to fix this.

isCgoGeneratedFile(T.obj.Pos()) && strings.HasPrefix(T.obj.Name(), "_Ctype_") 

fix cl

@adonovan
Copy link
Member

Well spotted! I didn't realize the compiler already had an official heuristic for isCgoGeneratedFile. Let's use that.

@cuiweixie
Copy link
Contributor

@alandonovan pointed out this hole in the current cgo detection of methods on C types, and I said it didn't seem worth worrying about, because who would put a method on a type alias? Interesting to see that people actually do this.

If anybody sees a simple way to fix this, by all means go for it.

I think this condition is simple to fix this.

isCgoGeneratedFile(T.obj.Pos()) && strings.HasPrefix(T.obj.Name(), "_Ctype_") 

fix cl

@ianlancetaylor is this condition ok,isCgoGeneratedFile(T.obj.Pos()) && strings.HasPrefix(T.obj.Name(), "Ctype") ?

@ianlancetaylor
Copy link
Member

@cuiweixie Yes. Thanks.

@deadprogram
Copy link

This is another very commonly used package that will no longer compile using Go 1.21: bugst/go-serial#162

@adonovan
Copy link
Member

This is another very commonly used package that will no longer compile using Go 1.21: bugst/go-serial#162

At the risk of sounding flippant, I might rephrase that as "another package that got away with invalid code". Fortunately the problematic cases all seem to be internal so it should be an easy fix.

deadprogram added a commit to deadprogram/go-serial that referenced this issue Jul 17, 2023
This is needed starting with Go 1.21 due to stricter enforcement of rules
about adding methods to existing types, now including C types.

See golang/go#60725 for further details.

Signed-off-by: deadprogram <ron@hybridgroup.com>
@deadprogram
Copy link

@adonovan indeed, I submitted a PR to that repo with fix.

cmaglie pushed a commit to deadprogram/go-serial that referenced this issue Aug 10, 2023
This is needed starting with Go 1.21 due to stricter enforcement of rules
about adding methods to existing types, now including C types.

See golang/go#60725 for further details.

Signed-off-by: deadprogram <ron@hybridgroup.com>
@griesemer griesemer assigned griesemer and unassigned mdempsky Sep 18, 2024
@griesemer griesemer removed this from the Backlog milestone Sep 18, 2024
@griesemer griesemer added this to the Go1.24 milestone Sep 18, 2024
@griesemer
Copy link
Contributor

Reassigned to me for 1.24 to make it visible. CL exists. Should review.

@griesemer
Copy link
Contributor

Pending CL CL 503596 still needs some work.

@dmitshur dmitshur moved this from Todo to In Progress in Go Compiler / Runtime Nov 13, 2024
@dmitshur dmitshur added the FixPending Issues that have a fix which has not yet been reviewed or submitted. label Nov 13, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/629715 mentions this issue: go/types, types2: disallow new methods on (aliases to) cgo-generated types

@griesemer griesemer removed help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Nov 19, 2024
@griesemer
Copy link
Contributor

@eliasnaur The pattern you are referring to in your example program appears (or appeared) in gioui.org/app/os_x11.go (see #59944). We fixed a crash with respect to that case. As the author of Gio, presumably you do not rely on this mechanism anymore since you filed this (current) issue? We are wondering if we can remove support from the compiler and make it an error going forward (cgo behavior is not covered by the Go 1 compatibility guarantee).

@eliasnaur
Copy link
Contributor Author

Absolutely, go ahead and make it an error. Thank you.

The current Gio code does rely on this behaviour, but I'll update it well before Go 1.24 is released if this issue is fixed.

@github-project-automation github-project-automation bot moved this from In Progress to Done in Go Compiler / Runtime Nov 20, 2024
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/630335 mentions this issue: doc: document new restriction on cgo-generated method receicer types

gopherbot pushed a commit that referenced this issue Nov 20, 2024
Follow-up on CL 629715.

For #60725.

Change-Id: I1b980ad44f73550b633c74fc881c70255e7d8565
Reviewed-on: https://go-review.googlesource.com/c/go/+/630335
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Bypass: Robert Griesemer <gri@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/630395 mentions this issue: go/types, types2: simplify Checker.resolveBaseTypeName (cleanup)

gopherbot pushed a commit that referenced this issue Nov 21, 2024
Method receivers that denote cgo-generated types are not permitted
per issues #60725 and #57926. There's no need to collect such methods
in the first place. Simplify Checker.resolveBaseTypeName so that it
doesn't find a base type name in these cases.

Also, simplify the test case for issue #59944 and update it to use
current cgo-generated output.

For #60725.
For #57926.
For #59944.

Change-Id: I70594daebc3d4d594c5b06be138f66f8927b0e58
Reviewed-on: https://go-review.googlesource.com/c/go/+/630395
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FixPending Issues that have a fix which has not yet been reviewed or submitted.
Projects
Development

No branches or pull requests

9 participants