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

Open
eliasnaur opened this issue Jun 11, 2023 · 15 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. help wanted NeedsFix The path to resolution is known, but the work has not been done.
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
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.

@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
Contributor

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

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

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

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

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
Contributor

@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>
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. help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
Development

No branches or pull requests

7 participants