[Bug go/65134] gccgo ignores the attribute "constructor" in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 Ian Lance Taylor changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #7 from Ian Lance Taylor --- This was fixed by the fix for PR 68255. *** This bug has been marked as a duplicate of bug 68255 ***
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #5 from boger at us dot ibm.com --- (In reply to Tatsushi Inagaki from comment #0) Created attachment 34813 [details] Example to reproduce the constructor problem Gccgo ignores a C-function with the constructor attribute in a subdirectory. In the attached example, gc executes a C-function init() in sub.go before a Go function main(), but gccgo does not: ~/example$ export GOPATH=$(pwd) ~/example$ /usr/local/go/bin/go version go version go1.4.2 linux/amd64 ~/example$ /usr/local/go/bin/go run src/main/main.go Hello from constructor Hello from main ~/example$ export LD_LIBRARY_PATH=/usr/local/gccgo/lib64:$LD_LIBRARY_PATH ~/example$ /usr/local/gccgo/bin/go version go version gccgo (GCC) 5.0.0 20150115 (experimental) linux/amd64 ~/example$ /usr/local/gccgo/bin/go run src/main/main.go Hello from main ~/example$ It seems this difference is due to that gccgo cannot detect a function with the constructor attribute in an archived objects created in a subdirectory. Is there any workaround to avoid this problem? Just to clarify this -- are you saying the problem that the gccgo linker is smart enough to determine that the function is not being used so it is discarded, but with gc it is not? So this is a difference in behavior but not actually a bug?
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #6 from Ian Lance Taylor ian at airs dot com --- No, I believe the problem is different. The gccgo build process stores objects in an archive, and relies on the system linker to pull in those objects. However, at least on ELF-based systems like GNU/Linux, the system linker does not link an object from an archive merely because it has a constructor. It only links an object from an archive if there is some reference to it: if the object defines a symbol that some other object, already included in the link, refers to. What I'm doing with the Go code is adding a reference, forcing the object to be linked in from the archive. Once the object is linked in, everything works. So although we want the reference, we don't want the reference to actually do anything. That is why I wrote the AlwaysFalse code: so that there is a function call, but the compiler can't see that the function will never be called. This is a standard problem with ELF linkers. See, e.g., http://stackoverflow.com/questions/6589772/gcc-functions-with-constructor-attribute-are-not-being-linked . This issue is not really Go-specific, except for the fact that the go tool build process when using gccgo uses archives. Perhaps it should change to work in some other way.
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #1 from Ian Lance Taylor ian at airs dot com --- It's pretty ugly, but a workaround is to drop something like this into sub.go: var AlwaysFalse bool func init() { if AlwaysFalse { C.init() } } The idea is to force in something that refers to the function that the compiler and linker aren't smart enough to discard.
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #2 from Tatsushi Inagaki e29253 at jp dot ibm.com --- (In reply to Ian Lance Taylor from comment #1) It's pretty ugly, but a workaround is to drop something like this into sub.go: var AlwaysFalse bool func init() { if AlwaysFalse { C.init() } } The idea is to force in something that refers to the function that the compiler and linker aren't smart enough to discard. Thank you very much for your suggestion. Don't we have to take special care at declaration or assignment of AlwaysFalse, so that the compiler will not eliminate the never-taken branch to C.init()?
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #3 from Ian Lance Taylor ian at airs dot com --- In principle, sure. In practice, since it's an exported variable, the compiler would have to see the entire program, which can't happen at present. If it ever can, then something else would have to be done.
[Bug go/65134] gccgo ignores the attribute constructor in a subdirectory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65134 --- Comment #4 from Tatsushi Inagaki e29253 at jp dot ibm.com --- I see. Thanks a lot!