From aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 6 Sep 2019 18:12:46 +0000 Subject: libgo: update to Go 1.13beta1 release Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497 From-SVN: r275473 --- libgo/misc/cgo/errors/errors_test.go | 15 +- libgo/misc/cgo/errors/ptr_test.go | 493 ++--- libgo/misc/cgo/errors/src/err1.go | 18 - libgo/misc/cgo/errors/src/err2.go | 13 - libgo/misc/cgo/errors/src/err3.go | 18 - libgo/misc/cgo/errors/src/err4.go | 15 - libgo/misc/cgo/errors/src/issue11097a.go | 15 - libgo/misc/cgo/errors/src/issue11097b.go | 15 - libgo/misc/cgo/errors/src/issue13129.go | 14 - libgo/misc/cgo/errors/src/issue13423.go | 12 - libgo/misc/cgo/errors/src/issue13467.go | 15 - libgo/misc/cgo/errors/src/issue13635.go | 24 - libgo/misc/cgo/errors/src/issue13830.go | 26 - libgo/misc/cgo/errors/src/issue14669.go | 23 - libgo/misc/cgo/errors/src/issue16116.go | 12 - libgo/misc/cgo/errors/src/issue16591.go | 17 - libgo/misc/cgo/errors/src/issue18452.go | 18 - libgo/misc/cgo/errors/src/issue18889.go | 7 - libgo/misc/cgo/errors/src/issue26745.go | 17 - libgo/misc/cgo/errors/src/issue28069.go | 26 - libgo/misc/cgo/errors/src/issue28721.go | 29 - libgo/misc/cgo/errors/src/issue7757.go | 14 - libgo/misc/cgo/errors/src/issue8442.go | 17 - libgo/misc/cgo/errors/src/long_double_size.go | 16 - libgo/misc/cgo/errors/src/malloc.go | 34 - libgo/misc/cgo/errors/testdata/err1.go | 22 + libgo/misc/cgo/errors/testdata/err2.go | 102 + libgo/misc/cgo/errors/testdata/err4.go | 15 + libgo/misc/cgo/errors/testdata/issue11097a.go | 15 + libgo/misc/cgo/errors/testdata/issue11097b.go | 15 + libgo/misc/cgo/errors/testdata/issue14669.go | 23 + libgo/misc/cgo/errors/testdata/issue18452.go | 18 + libgo/misc/cgo/errors/testdata/issue18889.go | 7 + libgo/misc/cgo/errors/testdata/issue28069.go | 26 + libgo/misc/cgo/errors/testdata/issue28721.go | 29 + libgo/misc/cgo/errors/testdata/long_double_size.go | 16 + libgo/misc/cgo/errors/testdata/malloc.go | 34 + libgo/misc/cgo/fortran/test.bash | 7 +- libgo/misc/cgo/life/c-life.c | 56 - libgo/misc/cgo/life/life.go | 41 - libgo/misc/cgo/life/life.h | 7 - libgo/misc/cgo/life/life_test.go | 64 + libgo/misc/cgo/life/main.go | 49 - libgo/misc/cgo/life/main.out | 16 - libgo/misc/cgo/life/overlaydir_test.go | 81 + libgo/misc/cgo/life/testdata/c-life.c | 56 + libgo/misc/cgo/life/testdata/life.go | 41 + libgo/misc/cgo/life/testdata/life.h | 7 + libgo/misc/cgo/life/testdata/main.go | 49 + libgo/misc/cgo/life/testdata/main.out | 16 + libgo/misc/cgo/stdio/chain.go | 48 - libgo/misc/cgo/stdio/chain.out | 55 - libgo/misc/cgo/stdio/fib.go | 52 - libgo/misc/cgo/stdio/fib.out | 91 - libgo/misc/cgo/stdio/file.go | 44 - libgo/misc/cgo/stdio/hello.go | 15 - libgo/misc/cgo/stdio/hello.out | 1 - libgo/misc/cgo/stdio/overlaydir_test.go | 81 + libgo/misc/cgo/stdio/run.out | 150 -- libgo/misc/cgo/stdio/stdio.go | 22 - libgo/misc/cgo/stdio/stdio_test.go | 64 + libgo/misc/cgo/stdio/testdata/chain.go | 48 + libgo/misc/cgo/stdio/testdata/chain.out | 55 + libgo/misc/cgo/stdio/testdata/fib.go | 52 + libgo/misc/cgo/stdio/testdata/fib.out | 91 + libgo/misc/cgo/stdio/testdata/hello.go | 15 + libgo/misc/cgo/stdio/testdata/hello.out | 1 + libgo/misc/cgo/stdio/testdata/run.out | 150 ++ libgo/misc/cgo/stdio/testdata/stdio/file.go | 44 + libgo/misc/cgo/stdio/testdata/stdio/stdio.go | 22 + libgo/misc/cgo/test/align.go | 76 - libgo/misc/cgo/test/api.go | 30 - libgo/misc/cgo/test/basic.go | 181 -- libgo/misc/cgo/test/callback.go | 6 +- libgo/misc/cgo/test/cflags.go | 32 - libgo/misc/cgo/test/cgo_linux_test.go | 13 +- libgo/misc/cgo/test/cgo_stubs_android_test.go | 1 - libgo/misc/cgo/test/cgo_test.go | 97 +- libgo/misc/cgo/test/checkconst.go | 33 - libgo/misc/cgo/test/complex.go | 24 - libgo/misc/cgo/test/cthread.go | 44 - libgo/misc/cgo/test/duplicate_symbol.go | 21 - libgo/misc/cgo/test/env.go | 41 - libgo/misc/cgo/test/exports.go | 18 - libgo/misc/cgo/test/fpvar.go | 50 - libgo/misc/cgo/test/gcc68255.go | 17 - libgo/misc/cgo/test/gcc68255/a.go | 17 - libgo/misc/cgo/test/gcc68255/c.c | 8 - libgo/misc/cgo/test/gcc68255/c.h | 5 - libgo/misc/cgo/test/helpers.go | 35 - libgo/misc/cgo/test/issue10303.go | 76 - libgo/misc/cgo/test/issue11925.go | 37 - libgo/misc/cgo/test/issue12030.go | 35 - libgo/misc/cgo/test/issue1222.go | 29 - libgo/misc/cgo/test/issue1328.go | 30 - libgo/misc/cgo/test/issue13402.go | 10 - libgo/misc/cgo/test/issue13930.go | 13 - libgo/misc/cgo/test/issue14838.go | 37 - libgo/misc/cgo/test/issue1560.go | 50 - libgo/misc/cgo/test/issue1635.go | 38 - libgo/misc/cgo/test/issue17065.go | 29 - libgo/misc/cgo/test/issue17537.go | 58 - libgo/misc/cgo/test/issue18126.go | 26 - libgo/misc/cgo/test/issue18146.go | 6 +- libgo/misc/cgo/test/issue18720.go | 54 - libgo/misc/cgo/test/issue20129.go | 33 - libgo/misc/cgo/test/issue20266.go | 21 - libgo/misc/cgo/test/issue20266/issue20266.h | 9 - libgo/misc/cgo/test/issue20369.go | 20 - libgo/misc/cgo/test/issue20910.go | 19 - libgo/misc/cgo/test/issue21668.go | 13 - libgo/misc/cgo/test/issue21708.go | 16 - libgo/misc/cgo/test/issue21809.go | 45 - libgo/misc/cgo/test/issue22958.go | 24 - libgo/misc/cgo/test/issue23356.go | 19 - libgo/misc/cgo/test/issue23555.go | 11 - libgo/misc/cgo/test/issue23555a/a.go | 12 - libgo/misc/cgo/test/issue23555b/a.go | 12 - libgo/misc/cgo/test/issue23720.go | 22 - libgo/misc/cgo/test/issue24161_darwin_test.go | 39 - libgo/misc/cgo/test/issue24161arg/def.go | 17 - libgo/misc/cgo/test/issue24161arg/use.go | 19 - libgo/misc/cgo/test/issue24161e0/main.go | 29 - libgo/misc/cgo/test/issue24161e1/main.go | 38 - libgo/misc/cgo/test/issue24161e2/main.go | 40 - libgo/misc/cgo/test/issue24161res/restype.go | 23 - libgo/misc/cgo/test/issue24206.go | 54 - libgo/misc/cgo/test/issue24206_generic.go | 13 - libgo/misc/cgo/test/issue2462.go | 102 - libgo/misc/cgo/test/issue25143.go | 22 - libgo/misc/cgo/test/issue26066.go | 19 - libgo/misc/cgo/test/issue26213/jni.h | 29 - libgo/misc/cgo/test/issue26213/test26213.go | 46 - libgo/misc/cgo/test/issue26430.go | 10 - libgo/misc/cgo/test/issue26430/a.go | 13 - libgo/misc/cgo/test/issue26430/b.go | 13 - libgo/misc/cgo/test/issue26517.go | 23 - libgo/misc/cgo/test/issue26743.go | 10 - libgo/misc/cgo/test/issue26743/a.go | 11 - libgo/misc/cgo/test/issue26743/b.go | 9 - libgo/misc/cgo/test/issue27054/egl.h | 7 - libgo/misc/cgo/test/issue27054/test27054.go | 17 - libgo/misc/cgo/test/issue27340.go | 12 - libgo/misc/cgo/test/issue27340/a.go | 42 - libgo/misc/cgo/test/issue28545.go | 26 - libgo/misc/cgo/test/issue28772.go | 12 - libgo/misc/cgo/test/issue28896.go | 83 - libgo/misc/cgo/test/issue29383.go | 19 - libgo/misc/cgo/test/issue29748.go | 22 - libgo/misc/cgo/test/issue29781.go | 17 - libgo/misc/cgo/test/issue30065.go | 38 - libgo/misc/cgo/test/issue3250.go | 95 - libgo/misc/cgo/test/issue3250w.go | 11 - libgo/misc/cgo/test/issue3261.go | 49 - libgo/misc/cgo/test/issue3729.go | 47 - libgo/misc/cgo/test/issue3729w.go | 16 - libgo/misc/cgo/test/issue3741.go | 22 - libgo/misc/cgo/test/issue3775.go | 39 - libgo/misc/cgo/test/issue3945.go | 22 - libgo/misc/cgo/test/issue4054a.go | 23 - libgo/misc/cgo/test/issue4054b.go | 23 - libgo/misc/cgo/test/issue4339.go | 17 - libgo/misc/cgo/test/issue4417.go | 42 - libgo/misc/cgo/test/issue4857.go | 15 - libgo/misc/cgo/test/issue5227.go | 38 - libgo/misc/cgo/test/issue5242.go | 31 - libgo/misc/cgo/test/issue5337.go | 31 - libgo/misc/cgo/test/issue5337w.go | 11 - libgo/misc/cgo/test/issue5548.go | 27 - libgo/misc/cgo/test/issue5603.go | 32 - libgo/misc/cgo/test/issue5740.go | 15 - libgo/misc/cgo/test/issue5986.go | 33 - libgo/misc/cgo/test/issue6128.go | 20 - libgo/misc/cgo/test/issue6390.go | 23 - libgo/misc/cgo/test/issue6472.go | 22 - libgo/misc/cgo/test/issue6506.go | 36 - libgo/misc/cgo/test/issue6612.go | 90 - libgo/misc/cgo/test/issue6833.go | 27 - libgo/misc/cgo/test/issue6907.go | 33 - libgo/misc/cgo/test/issue6907export.go | 30 - libgo/misc/cgo/test/issue7560.go | 44 - libgo/misc/cgo/test/issue7665.go | 25 - libgo/misc/cgo/test/issue7786.go | 51 - libgo/misc/cgo/test/issue7978.go | 115 -- libgo/misc/cgo/test/issue8092.go | 36 - libgo/misc/cgo/test/issue8331a.go | 15 - libgo/misc/cgo/test/issue8331b.go | 13 - libgo/misc/cgo/test/issue8428.go | 55 - libgo/misc/cgo/test/issue8441.go | 27 - libgo/misc/cgo/test/issue8756.go | 17 - libgo/misc/cgo/test/issue8756/issue8756.go | 11 - libgo/misc/cgo/test/issue8811.go | 22 - libgo/misc/cgo/test/issue8828.go | 16 - libgo/misc/cgo/test/issue8828/issue8828.c | 7 - libgo/misc/cgo/test/issue8828/trivial.go | 8 - libgo/misc/cgo/test/issue9026.go | 9 - libgo/misc/cgo/test/issue9026/issue9026.go | 36 - libgo/misc/cgo/test/issue9400/asm_386.s | 27 - libgo/misc/cgo/test/issue9400/asm_amd64x.s | 27 - libgo/misc/cgo/test/issue9400/asm_arm.s | 39 - libgo/misc/cgo/test/issue9400/asm_arm64.s | 39 - libgo/misc/cgo/test/issue9400/asm_mips64x.s | 33 - libgo/misc/cgo/test/issue9400/asm_mipsx.s | 31 - libgo/misc/cgo/test/issue9400/asm_ppc64x.s | 32 - libgo/misc/cgo/test/issue9400/asm_s390x.s | 26 - libgo/misc/cgo/test/issue9400/gccgo.go | 26 - libgo/misc/cgo/test/issue9400/stubs.go | 11 - libgo/misc/cgo/test/issue9400_linux.go | 58 - libgo/misc/cgo/test/issue9510.go | 24 - libgo/misc/cgo/test/issue9510a/a.go | 15 - libgo/misc/cgo/test/issue9510b/b.go | 15 - libgo/misc/cgo/test/issue9557.go | 36 - libgo/misc/cgo/test/overlaydir_test.go | 81 + libgo/misc/cgo/test/pkg_test.go | 69 + libgo/misc/cgo/test/sigaltstack.go | 2 +- libgo/misc/cgo/test/test.go | 2104 ++++++++++++++++++++ libgo/misc/cgo/test/test22906.go | 74 - libgo/misc/cgo/test/test26213.go | 15 - libgo/misc/cgo/test/test27660.go | 61 - libgo/misc/cgo/test/test_unix.go | 11 + libgo/misc/cgo/test/test_windows.go | 9 + libgo/misc/cgo/test/testdata/cgo_linux_test.go | 9 + libgo/misc/cgo/test/testdata/cgo_test.go | 18 + libgo/misc/cgo/test/testdata/gcc68255.go | 17 + libgo/misc/cgo/test/testdata/gcc68255/a.go | 17 + libgo/misc/cgo/test/testdata/gcc68255/c.c | 8 + libgo/misc/cgo/test/testdata/gcc68255/c.h | 5 + libgo/misc/cgo/test/testdata/issue20266.go | 21 + .../misc/cgo/test/testdata/issue20266/issue20266.h | 9 + libgo/misc/cgo/test/testdata/issue23555.go | 11 + libgo/misc/cgo/test/testdata/issue23555a/a.go | 12 + libgo/misc/cgo/test/testdata/issue23555b/a.go | 12 + .../cgo/test/testdata/issue24161_darwin_test.go | 39 + libgo/misc/cgo/test/testdata/issue24161arg/def.go | 17 + libgo/misc/cgo/test/testdata/issue24161arg/use.go | 19 + libgo/misc/cgo/test/testdata/issue24161e0/main.go | 29 + libgo/misc/cgo/test/testdata/issue24161e1/main.go | 38 + libgo/misc/cgo/test/testdata/issue24161e2/main.go | 40 + .../cgo/test/testdata/issue24161res/restype.go | 23 + libgo/misc/cgo/test/testdata/issue26213/jni.h | 29 + .../misc/cgo/test/testdata/issue26213/test26213.go | 46 + libgo/misc/cgo/test/testdata/issue26430.go | 10 + libgo/misc/cgo/test/testdata/issue26430/a.go | 13 + libgo/misc/cgo/test/testdata/issue26430/b.go | 13 + libgo/misc/cgo/test/testdata/issue26743.go | 10 + libgo/misc/cgo/test/testdata/issue26743/a.go | 11 + libgo/misc/cgo/test/testdata/issue26743/b.go | 9 + libgo/misc/cgo/test/testdata/issue27054/egl.h | 7 + .../misc/cgo/test/testdata/issue27054/test27054.go | 17 + libgo/misc/cgo/test/testdata/issue27340.go | 12 + libgo/misc/cgo/test/testdata/issue27340/a.go | 42 + libgo/misc/cgo/test/testdata/issue29563.go | 12 + libgo/misc/cgo/test/testdata/issue29563/weak.go | 13 + libgo/misc/cgo/test/testdata/issue29563/weak1.c | 11 + libgo/misc/cgo/test/testdata/issue29563/weak2.c | 11 + libgo/misc/cgo/test/testdata/issue8756.go | 17 + .../misc/cgo/test/testdata/issue8756/issue8756.go | 11 + libgo/misc/cgo/test/testdata/issue8828.go | 16 + libgo/misc/cgo/test/testdata/issue8828/issue8828.c | 7 + libgo/misc/cgo/test/testdata/issue8828/trivial.go | 8 + libgo/misc/cgo/test/testdata/issue9026.go | 9 + .../misc/cgo/test/testdata/issue9026/issue9026.go | 36 + libgo/misc/cgo/test/testdata/issue9400/asm_386.s | 27 + .../misc/cgo/test/testdata/issue9400/asm_amd64x.s | 27 + libgo/misc/cgo/test/testdata/issue9400/asm_arm.s | 39 + libgo/misc/cgo/test/testdata/issue9400/asm_arm64.s | 39 + .../misc/cgo/test/testdata/issue9400/asm_mips64x.s | 33 + libgo/misc/cgo/test/testdata/issue9400/asm_mipsx.s | 31 + .../misc/cgo/test/testdata/issue9400/asm_ppc64x.s | 32 + libgo/misc/cgo/test/testdata/issue9400/asm_s390x.s | 26 + libgo/misc/cgo/test/testdata/issue9400/gccgo.go | 26 + libgo/misc/cgo/test/testdata/issue9400/stubs.go | 11 + libgo/misc/cgo/test/testdata/issue9400_linux.go | 58 + libgo/misc/cgo/test/testdata/issue9510.go | 24 + libgo/misc/cgo/test/testdata/issue9510a/a.go | 15 + libgo/misc/cgo/test/testdata/issue9510b/b.go | 15 + libgo/misc/cgo/test/testdata/test26213.go | 15 + libgo/misc/cgo/test/testx.go | 519 +++++ libgo/misc/cgo/test/twoargs.go | 22 - libgo/misc/cgo/testcarchive/carchive_test.go | 171 +- libgo/misc/cgo/testcarchive/main.c | 48 - libgo/misc/cgo/testcarchive/main2.c | 232 --- libgo/misc/cgo/testcarchive/main3.c | 189 -- libgo/misc/cgo/testcarchive/main4.c | 197 -- libgo/misc/cgo/testcarchive/main5.c | 98 - libgo/misc/cgo/testcarchive/main6.c | 34 - libgo/misc/cgo/testcarchive/main_unix.c | 59 - libgo/misc/cgo/testcarchive/main_windows.c | 17 - libgo/misc/cgo/testcarchive/overlaydir_test.go | 81 + libgo/misc/cgo/testcarchive/src/libgo/libgo.go | 53 - libgo/misc/cgo/testcarchive/src/libgo2/libgo2.go | 80 - libgo/misc/cgo/testcarchive/src/libgo3/libgo3.go | 56 - libgo/misc/cgo/testcarchive/src/libgo4/libgo4.go | 52 - libgo/misc/cgo/testcarchive/src/libgo6/sigprof.go | 25 - libgo/misc/cgo/testcarchive/src/p/p.go | 10 - .../misc/cgo/testcarchive/testdata/libgo/libgo.go | 53 + .../cgo/testcarchive/testdata/libgo2/libgo2.go | 80 + .../cgo/testcarchive/testdata/libgo3/libgo3.go | 56 + .../cgo/testcarchive/testdata/libgo4/libgo4.go | 52 + .../cgo/testcarchive/testdata/libgo6/sigprof.go | 25 + libgo/misc/cgo/testcarchive/testdata/main.c | 48 + libgo/misc/cgo/testcarchive/testdata/main2.c | 232 +++ libgo/misc/cgo/testcarchive/testdata/main3.c | 189 ++ libgo/misc/cgo/testcarchive/testdata/main4.c | 204 ++ libgo/misc/cgo/testcarchive/testdata/main5.c | 100 + libgo/misc/cgo/testcarchive/testdata/main6.c | 34 + libgo/misc/cgo/testcarchive/testdata/main_unix.c | 59 + .../misc/cgo/testcarchive/testdata/main_windows.c | 17 + libgo/misc/cgo/testcarchive/testdata/p/p.go | 10 + libgo/misc/cgo/testcshared/cshared_test.go | 170 +- libgo/misc/cgo/testcshared/main0.c | 42 - libgo/misc/cgo/testcshared/main1.c | 69 - libgo/misc/cgo/testcshared/main2.c | 56 - libgo/misc/cgo/testcshared/main3.c | 29 - libgo/misc/cgo/testcshared/main4.c | 215 -- libgo/misc/cgo/testcshared/main5.c | 199 -- libgo/misc/cgo/testcshared/overlaydir_test.go | 81 + libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go | 12 - libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c | 9 - libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go | 22 - libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go | 22 - libgo/misc/cgo/testcshared/src/libgo/libgo.go | 46 - libgo/misc/cgo/testcshared/src/libgo2/dup2.go | 13 - libgo/misc/cgo/testcshared/src/libgo2/dup3.go | 13 - libgo/misc/cgo/testcshared/src/libgo2/libgo2.go | 52 - libgo/misc/cgo/testcshared/src/libgo4/libgo4.go | 45 - libgo/misc/cgo/testcshared/src/libgo5/libgo5.go | 44 - libgo/misc/cgo/testcshared/src/p/p.go | 13 - .../cgo/testcshared/testdata/go2c2go/go/shlib.go | 12 + libgo/misc/cgo/testcshared/testdata/go2c2go/m1/c.c | 9 + .../cgo/testcshared/testdata/go2c2go/m1/main.go | 22 + .../cgo/testcshared/testdata/go2c2go/m2/main.go | 22 + libgo/misc/cgo/testcshared/testdata/libgo/libgo.go | 46 + libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go | 13 + libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go | 13 + .../misc/cgo/testcshared/testdata/libgo2/libgo2.go | 52 + .../misc/cgo/testcshared/testdata/libgo4/libgo4.go | 45 + .../misc/cgo/testcshared/testdata/libgo5/libgo5.go | 44 + libgo/misc/cgo/testcshared/testdata/main0.c | 42 + libgo/misc/cgo/testcshared/testdata/main1.c | 69 + libgo/misc/cgo/testcshared/testdata/main2.c | 56 + libgo/misc/cgo/testcshared/testdata/main3.c | 29 + libgo/misc/cgo/testcshared/testdata/main4.c | 215 ++ libgo/misc/cgo/testcshared/testdata/main5.c | 199 ++ libgo/misc/cgo/testcshared/testdata/p/p.go | 13 + libgo/misc/cgo/testgodefs/anonunion.go | 26 - libgo/misc/cgo/testgodefs/fieldtypedef.go | 18 - libgo/misc/cgo/testgodefs/issue8478.go | 20 - libgo/misc/cgo/testgodefs/main.go | 15 - libgo/misc/cgo/testgodefs/test.bash | 4 +- libgo/misc/cgo/testgodefs/testdata/anonunion.go | 26 + libgo/misc/cgo/testgodefs/testdata/fieldtypedef.go | 18 + libgo/misc/cgo/testgodefs/testdata/issue8478.go | 20 + libgo/misc/cgo/testgodefs/testdata/main.go | 15 + .../cgo/testplugin/altpath/src/common/common.go | 11 - .../testplugin/altpath/src/plugin-mismatch/main.go | 17 - .../testplugin/altpath/testdata/common/common.go | 11 + .../altpath/testdata/plugin-mismatch/main.go | 17 + libgo/misc/cgo/testplugin/overlaydir_test.go | 81 + libgo/misc/cgo/testplugin/plugin_test.go | 203 ++ libgo/misc/cgo/testplugin/src/checkdwarf/main.go | 106 - libgo/misc/cgo/testplugin/src/common/common.go | 11 - libgo/misc/cgo/testplugin/src/host/host.go | 176 -- libgo/misc/cgo/testplugin/src/iface/main.go | 46 - libgo/misc/cgo/testplugin/src/iface_a/a.go | 17 - libgo/misc/cgo/testplugin/src/iface_b/b.go | 17 - libgo/misc/cgo/testplugin/src/iface_i/i.go | 17 - libgo/misc/cgo/testplugin/src/issue18584/main.go | 23 - libgo/misc/cgo/testplugin/src/issue18584/plugin.go | 19 - .../issue18676/dynamodbstreamsevt/definition.go | 13 - libgo/misc/cgo/testplugin/src/issue18676/main.go | 31 - libgo/misc/cgo/testplugin/src/issue18676/plugin.go | 11 - libgo/misc/cgo/testplugin/src/issue19418/main.go | 29 - libgo/misc/cgo/testplugin/src/issue19418/plugin.go | 7 - libgo/misc/cgo/testplugin/src/issue19529/plugin.go | 15 - libgo/misc/cgo/testplugin/src/issue19534/main.go | 23 - libgo/misc/cgo/testplugin/src/issue19534/plugin.go | 9 - libgo/misc/cgo/testplugin/src/issue22175/main.go | 28 - .../misc/cgo/testplugin/src/issue22175/plugin1.go | 21 - .../misc/cgo/testplugin/src/issue22175/plugin2.go | 9 - .../misc/cgo/testplugin/src/issue22295.pkg/main.go | 28 - .../cgo/testplugin/src/issue22295.pkg/plugin.go | 16 - libgo/misc/cgo/testplugin/src/issue24351/main.go | 21 - libgo/misc/cgo/testplugin/src/issue24351/plugin.go | 14 - libgo/misc/cgo/testplugin/src/issue25756/main.go | 52 - .../cgo/testplugin/src/issue25756/plugin/c-life.c | 56 - .../cgo/testplugin/src/issue25756/plugin/life.go | 39 - .../cgo/testplugin/src/issue25756/plugin/life.h | 7 - libgo/misc/cgo/testplugin/src/plugin1/plugin1.go | 56 - libgo/misc/cgo/testplugin/src/plugin2/plugin2.go | 43 - .../misc/cgo/testplugin/src/sub/plugin1/plugin1.go | 23 - libgo/misc/cgo/testplugin/test.bash | 109 - .../cgo/testplugin/testdata/checkdwarf/main.go | 106 + .../misc/cgo/testplugin/testdata/common/common.go | 11 + libgo/misc/cgo/testplugin/testdata/host/host.go | 176 ++ libgo/misc/cgo/testplugin/testdata/iface/main.go | 47 + libgo/misc/cgo/testplugin/testdata/iface_a/a.go | 17 + libgo/misc/cgo/testplugin/testdata/iface_b/b.go | 17 + libgo/misc/cgo/testplugin/testdata/iface_i/i.go | 17 + .../cgo/testplugin/testdata/issue18584/main.go | 23 + .../cgo/testplugin/testdata/issue18584/plugin.go | 19 + .../issue18676/dynamodbstreamsevt/definition.go | 13 + .../cgo/testplugin/testdata/issue18676/main.go | 31 + .../cgo/testplugin/testdata/issue18676/plugin.go | 11 + .../cgo/testplugin/testdata/issue19418/main.go | 29 + .../cgo/testplugin/testdata/issue19418/plugin.go | 7 + .../cgo/testplugin/testdata/issue19529/plugin.go | 15 + .../cgo/testplugin/testdata/issue19534/main.go | 23 + .../cgo/testplugin/testdata/issue19534/plugin.go | 9 + .../cgo/testplugin/testdata/issue22175/main.go | 28 + .../cgo/testplugin/testdata/issue22175/plugin1.go | 21 + .../cgo/testplugin/testdata/issue22175/plugin2.go | 9 + .../cgo/testplugin/testdata/issue22295.pkg/main.go | 28 + .../testplugin/testdata/issue22295.pkg/plugin.go | 16 + .../cgo/testplugin/testdata/issue24351/main.go | 21 + .../cgo/testplugin/testdata/issue24351/plugin.go | 14 + .../cgo/testplugin/testdata/issue25756/main.go | 52 + .../testplugin/testdata/issue25756/plugin/c-life.c | 56 + .../testplugin/testdata/issue25756/plugin/life.go | 39 + .../testplugin/testdata/issue25756/plugin/life.h | 7 + .../cgo/testplugin/testdata/plugin1/plugin1.go | 57 + .../cgo/testplugin/testdata/plugin2/plugin2.go | 44 + .../cgo/testplugin/testdata/sub/plugin1/plugin1.go | 23 + .../misc/cgo/testplugin/testdata/unnamed1/main.go | 25 + .../misc/cgo/testplugin/testdata/unnamed2/main.go | 23 + libgo/misc/cgo/testplugin/unnamed1/main.go | 23 - libgo/misc/cgo/testplugin/unnamed2/main.go | 21 - libgo/misc/cgo/testsanitizers/cc_test.go | 2 +- libgo/misc/cgo/testsanitizers/src/msan.go | 35 - libgo/misc/cgo/testsanitizers/src/msan2.go | 35 - libgo/misc/cgo/testsanitizers/src/msan2_cmsan.go | 38 - libgo/misc/cgo/testsanitizers/src/msan3.go | 33 - libgo/misc/cgo/testsanitizers/src/msan4.go | 50 - libgo/misc/cgo/testsanitizers/src/msan5.go | 57 - libgo/misc/cgo/testsanitizers/src/msan6.go | 72 - libgo/misc/cgo/testsanitizers/src/msan_fail.go | 36 - libgo/misc/cgo/testsanitizers/src/msan_shared.go | 12 - libgo/misc/cgo/testsanitizers/src/tsan.go | 44 - libgo/misc/cgo/testsanitizers/src/tsan10.go | 31 - libgo/misc/cgo/testsanitizers/src/tsan11.go | 55 - libgo/misc/cgo/testsanitizers/src/tsan12.go | 35 - libgo/misc/cgo/testsanitizers/src/tsan2.go | 55 - libgo/misc/cgo/testsanitizers/src/tsan3.go | 40 - libgo/misc/cgo/testsanitizers/src/tsan4.go | 34 - libgo/misc/cgo/testsanitizers/src/tsan5.go | 51 - libgo/misc/cgo/testsanitizers/src/tsan6.go | 49 - libgo/misc/cgo/testsanitizers/src/tsan7.go | 40 - libgo/misc/cgo/testsanitizers/src/tsan8.go | 60 - libgo/misc/cgo/testsanitizers/src/tsan9.go | 67 - libgo/misc/cgo/testsanitizers/src/tsan_shared.go | 63 - libgo/misc/cgo/testsanitizers/testdata/msan.go | 35 + libgo/misc/cgo/testsanitizers/testdata/msan2.go | 35 + .../cgo/testsanitizers/testdata/msan2_cmsan.go | 38 + libgo/misc/cgo/testsanitizers/testdata/msan3.go | 33 + libgo/misc/cgo/testsanitizers/testdata/msan4.go | 50 + libgo/misc/cgo/testsanitizers/testdata/msan5.go | 57 + libgo/misc/cgo/testsanitizers/testdata/msan6.go | 72 + .../misc/cgo/testsanitizers/testdata/msan_fail.go | 36 + .../cgo/testsanitizers/testdata/msan_shared.go | 12 + libgo/misc/cgo/testsanitizers/testdata/tsan.go | 44 + libgo/misc/cgo/testsanitizers/testdata/tsan10.go | 31 + libgo/misc/cgo/testsanitizers/testdata/tsan11.go | 55 + libgo/misc/cgo/testsanitizers/testdata/tsan12.go | 35 + libgo/misc/cgo/testsanitizers/testdata/tsan2.go | 55 + libgo/misc/cgo/testsanitizers/testdata/tsan3.go | 40 + libgo/misc/cgo/testsanitizers/testdata/tsan4.go | 34 + libgo/misc/cgo/testsanitizers/testdata/tsan5.go | 51 + libgo/misc/cgo/testsanitizers/testdata/tsan6.go | 49 + libgo/misc/cgo/testsanitizers/testdata/tsan7.go | 40 + libgo/misc/cgo/testsanitizers/testdata/tsan8.go | 60 + libgo/misc/cgo/testsanitizers/testdata/tsan9.go | 67 + .../cgo/testsanitizers/testdata/tsan_shared.go | 63 + libgo/misc/cgo/testsanitizers/tsan_test.go | 4 - libgo/misc/cgo/testshared/overlaydir_test.go | 81 + libgo/misc/cgo/testshared/shared_test.go | 340 ++-- libgo/misc/cgo/testshared/src/dep2/dep2.go | 15 - libgo/misc/cgo/testshared/src/dep3/dep3.go | 22 - libgo/misc/cgo/testshared/src/depBase/asm.s | 10 - libgo/misc/cgo/testshared/src/depBase/dep.go | 37 - libgo/misc/cgo/testshared/src/depBase/gccgo.go | 9 - libgo/misc/cgo/testshared/src/depBase/stubs.go | 9 - libgo/misc/cgo/testshared/src/division/division.go | 17 - libgo/misc/cgo/testshared/src/exe/exe.go | 44 - libgo/misc/cgo/testshared/src/exe2/exe2.go | 8 - libgo/misc/cgo/testshared/src/exe3/exe3.go | 7 - libgo/misc/cgo/testshared/src/execgo/exe.go | 8 - libgo/misc/cgo/testshared/src/explicit/explicit.go | 9 - libgo/misc/cgo/testshared/src/global/main.go | 71 - libgo/misc/cgo/testshared/src/globallib/global.go | 17 - libgo/misc/cgo/testshared/src/iface/main.go | 17 - libgo/misc/cgo/testshared/src/iface_a/a.go | 17 - libgo/misc/cgo/testshared/src/iface_b/b.go | 17 - libgo/misc/cgo/testshared/src/iface_i/i.go | 17 - libgo/misc/cgo/testshared/src/implicit/implicit.go | 5 - .../cgo/testshared/src/implicitcmd/implicitcmd.go | 10 - libgo/misc/cgo/testshared/src/issue25065/a.go | 20 - libgo/misc/cgo/testshared/src/trivial/trivial.go | 9 - libgo/misc/cgo/testshared/testdata/dep2/dep2.go | 15 + libgo/misc/cgo/testshared/testdata/dep3/dep3.go | 22 + libgo/misc/cgo/testshared/testdata/depBase/asm.s | 10 + libgo/misc/cgo/testshared/testdata/depBase/dep.go | 37 + .../misc/cgo/testshared/testdata/depBase/gccgo.go | 9 + .../misc/cgo/testshared/testdata/depBase/stubs.go | 9 + .../cgo/testshared/testdata/division/division.go | 17 + libgo/misc/cgo/testshared/testdata/exe/exe.go | 45 + libgo/misc/cgo/testshared/testdata/exe2/exe2.go | 8 + libgo/misc/cgo/testshared/testdata/exe3/exe3.go | 7 + libgo/misc/cgo/testshared/testdata/execgo/exe.go | 8 + .../cgo/testshared/testdata/explicit/explicit.go | 9 + libgo/misc/cgo/testshared/testdata/global/main.go | 71 + .../cgo/testshared/testdata/globallib/global.go | 17 + libgo/misc/cgo/testshared/testdata/iface/main.go | 17 + libgo/misc/cgo/testshared/testdata/iface_a/a.go | 17 + libgo/misc/cgo/testshared/testdata/iface_b/b.go | 17 + libgo/misc/cgo/testshared/testdata/iface_i/i.go | 17 + .../cgo/testshared/testdata/implicit/implicit.go | 5 + .../testshared/testdata/implicitcmd/implicitcmd.go | 10 + libgo/misc/cgo/testshared/testdata/issue25065/a.go | 20 + .../cgo/testshared/testdata/trivial/trivial.go | 9 + libgo/misc/cgo/testso/cgoso.c | 14 - libgo/misc/cgo/testso/cgoso.go | 31 - libgo/misc/cgo/testso/cgoso_c.c | 30 - libgo/misc/cgo/testso/cgoso_unix.go | 20 - libgo/misc/cgo/testso/main.go | 13 - libgo/misc/cgo/testso/noso_test.go | 9 + libgo/misc/cgo/testso/overlaydir_test.go | 81 + libgo/misc/cgo/testso/so_test.go | 140 ++ libgo/misc/cgo/testso/testdata/cgoso.c | 14 + libgo/misc/cgo/testso/testdata/cgoso.go | 32 + libgo/misc/cgo/testso/testdata/cgoso_c.c | 39 + libgo/misc/cgo/testso/testdata/cgoso_unix.go | 20 + libgo/misc/cgo/testso/testdata/main.go | 13 + libgo/misc/cgo/testsovar/cgoso.go | 43 - libgo/misc/cgo/testsovar/cgoso_c.c | 7 - libgo/misc/cgo/testsovar/cgoso_c.h | 17 - libgo/misc/cgo/testsovar/main.go | 13 - libgo/misc/cgo/testsovar/noso_test.go | 9 + libgo/misc/cgo/testsovar/overlaydir_test.go | 81 + libgo/misc/cgo/testsovar/so_test.go | 140 ++ libgo/misc/cgo/testsovar/testdata/cgoso.go | 44 + libgo/misc/cgo/testsovar/testdata/cgoso_c.c | 7 + libgo/misc/cgo/testsovar/testdata/cgoso_c.h | 17 + libgo/misc/cgo/testsovar/testdata/main.go | 13 + 543 files changed, 11677 insertions(+), 10886 deletions(-) delete mode 100644 libgo/misc/cgo/errors/src/err1.go delete mode 100644 libgo/misc/cgo/errors/src/err2.go delete mode 100644 libgo/misc/cgo/errors/src/err3.go delete mode 100644 libgo/misc/cgo/errors/src/err4.go delete mode 100644 libgo/misc/cgo/errors/src/issue11097a.go delete mode 100644 libgo/misc/cgo/errors/src/issue11097b.go delete mode 100644 libgo/misc/cgo/errors/src/issue13129.go delete mode 100644 libgo/misc/cgo/errors/src/issue13423.go delete mode 100644 libgo/misc/cgo/errors/src/issue13467.go delete mode 100644 libgo/misc/cgo/errors/src/issue13635.go delete mode 100644 libgo/misc/cgo/errors/src/issue13830.go delete mode 100644 libgo/misc/cgo/errors/src/issue14669.go delete mode 100644 libgo/misc/cgo/errors/src/issue16116.go delete mode 100644 libgo/misc/cgo/errors/src/issue16591.go delete mode 100644 libgo/misc/cgo/errors/src/issue18452.go delete mode 100644 libgo/misc/cgo/errors/src/issue18889.go delete mode 100644 libgo/misc/cgo/errors/src/issue26745.go delete mode 100644 libgo/misc/cgo/errors/src/issue28069.go delete mode 100644 libgo/misc/cgo/errors/src/issue28721.go delete mode 100644 libgo/misc/cgo/errors/src/issue7757.go delete mode 100644 libgo/misc/cgo/errors/src/issue8442.go delete mode 100644 libgo/misc/cgo/errors/src/long_double_size.go delete mode 100644 libgo/misc/cgo/errors/src/malloc.go create mode 100644 libgo/misc/cgo/errors/testdata/err1.go create mode 100644 libgo/misc/cgo/errors/testdata/err2.go create mode 100644 libgo/misc/cgo/errors/testdata/err4.go create mode 100644 libgo/misc/cgo/errors/testdata/issue11097a.go create mode 100644 libgo/misc/cgo/errors/testdata/issue11097b.go create mode 100644 libgo/misc/cgo/errors/testdata/issue14669.go create mode 100644 libgo/misc/cgo/errors/testdata/issue18452.go create mode 100644 libgo/misc/cgo/errors/testdata/issue18889.go create mode 100644 libgo/misc/cgo/errors/testdata/issue28069.go create mode 100644 libgo/misc/cgo/errors/testdata/issue28721.go create mode 100644 libgo/misc/cgo/errors/testdata/long_double_size.go create mode 100644 libgo/misc/cgo/errors/testdata/malloc.go delete mode 100644 libgo/misc/cgo/life/c-life.c delete mode 100644 libgo/misc/cgo/life/life.go delete mode 100644 libgo/misc/cgo/life/life.h create mode 100644 libgo/misc/cgo/life/life_test.go delete mode 100644 libgo/misc/cgo/life/main.go delete mode 100644 libgo/misc/cgo/life/main.out create mode 100644 libgo/misc/cgo/life/overlaydir_test.go create mode 100644 libgo/misc/cgo/life/testdata/c-life.c create mode 100644 libgo/misc/cgo/life/testdata/life.go create mode 100644 libgo/misc/cgo/life/testdata/life.h create mode 100644 libgo/misc/cgo/life/testdata/main.go create mode 100644 libgo/misc/cgo/life/testdata/main.out delete mode 100644 libgo/misc/cgo/stdio/chain.go delete mode 100644 libgo/misc/cgo/stdio/chain.out delete mode 100644 libgo/misc/cgo/stdio/fib.go delete mode 100644 libgo/misc/cgo/stdio/fib.out delete mode 100644 libgo/misc/cgo/stdio/file.go delete mode 100644 libgo/misc/cgo/stdio/hello.go delete mode 100644 libgo/misc/cgo/stdio/hello.out create mode 100644 libgo/misc/cgo/stdio/overlaydir_test.go delete mode 100644 libgo/misc/cgo/stdio/run.out delete mode 100644 libgo/misc/cgo/stdio/stdio.go create mode 100644 libgo/misc/cgo/stdio/stdio_test.go create mode 100644 libgo/misc/cgo/stdio/testdata/chain.go create mode 100644 libgo/misc/cgo/stdio/testdata/chain.out create mode 100644 libgo/misc/cgo/stdio/testdata/fib.go create mode 100644 libgo/misc/cgo/stdio/testdata/fib.out create mode 100644 libgo/misc/cgo/stdio/testdata/hello.go create mode 100644 libgo/misc/cgo/stdio/testdata/hello.out create mode 100644 libgo/misc/cgo/stdio/testdata/run.out create mode 100644 libgo/misc/cgo/stdio/testdata/stdio/file.go create mode 100644 libgo/misc/cgo/stdio/testdata/stdio/stdio.go delete mode 100644 libgo/misc/cgo/test/align.go delete mode 100644 libgo/misc/cgo/test/api.go delete mode 100644 libgo/misc/cgo/test/basic.go delete mode 100644 libgo/misc/cgo/test/cflags.go delete mode 100644 libgo/misc/cgo/test/checkconst.go delete mode 100644 libgo/misc/cgo/test/complex.go delete mode 100644 libgo/misc/cgo/test/cthread.go delete mode 100644 libgo/misc/cgo/test/duplicate_symbol.go delete mode 100644 libgo/misc/cgo/test/env.go delete mode 100644 libgo/misc/cgo/test/exports.go delete mode 100644 libgo/misc/cgo/test/fpvar.go delete mode 100644 libgo/misc/cgo/test/gcc68255.go delete mode 100644 libgo/misc/cgo/test/gcc68255/a.go delete mode 100644 libgo/misc/cgo/test/gcc68255/c.c delete mode 100644 libgo/misc/cgo/test/gcc68255/c.h delete mode 100644 libgo/misc/cgo/test/helpers.go delete mode 100644 libgo/misc/cgo/test/issue10303.go delete mode 100644 libgo/misc/cgo/test/issue11925.go delete mode 100644 libgo/misc/cgo/test/issue12030.go delete mode 100644 libgo/misc/cgo/test/issue1222.go delete mode 100644 libgo/misc/cgo/test/issue1328.go delete mode 100644 libgo/misc/cgo/test/issue13402.go delete mode 100644 libgo/misc/cgo/test/issue13930.go delete mode 100644 libgo/misc/cgo/test/issue14838.go delete mode 100644 libgo/misc/cgo/test/issue1560.go delete mode 100644 libgo/misc/cgo/test/issue1635.go delete mode 100644 libgo/misc/cgo/test/issue17065.go delete mode 100644 libgo/misc/cgo/test/issue17537.go delete mode 100644 libgo/misc/cgo/test/issue18126.go delete mode 100644 libgo/misc/cgo/test/issue18720.go delete mode 100644 libgo/misc/cgo/test/issue20129.go delete mode 100644 libgo/misc/cgo/test/issue20266.go delete mode 100644 libgo/misc/cgo/test/issue20266/issue20266.h delete mode 100644 libgo/misc/cgo/test/issue20369.go delete mode 100644 libgo/misc/cgo/test/issue20910.go delete mode 100644 libgo/misc/cgo/test/issue21668.go delete mode 100644 libgo/misc/cgo/test/issue21708.go delete mode 100644 libgo/misc/cgo/test/issue21809.go delete mode 100644 libgo/misc/cgo/test/issue22958.go delete mode 100644 libgo/misc/cgo/test/issue23356.go delete mode 100644 libgo/misc/cgo/test/issue23555.go delete mode 100644 libgo/misc/cgo/test/issue23555a/a.go delete mode 100644 libgo/misc/cgo/test/issue23555b/a.go delete mode 100644 libgo/misc/cgo/test/issue23720.go delete mode 100644 libgo/misc/cgo/test/issue24161_darwin_test.go delete mode 100644 libgo/misc/cgo/test/issue24161arg/def.go delete mode 100644 libgo/misc/cgo/test/issue24161arg/use.go delete mode 100644 libgo/misc/cgo/test/issue24161e0/main.go delete mode 100644 libgo/misc/cgo/test/issue24161e1/main.go delete mode 100644 libgo/misc/cgo/test/issue24161e2/main.go delete mode 100644 libgo/misc/cgo/test/issue24161res/restype.go delete mode 100644 libgo/misc/cgo/test/issue24206.go delete mode 100644 libgo/misc/cgo/test/issue24206_generic.go delete mode 100644 libgo/misc/cgo/test/issue2462.go delete mode 100644 libgo/misc/cgo/test/issue25143.go delete mode 100644 libgo/misc/cgo/test/issue26066.go delete mode 100644 libgo/misc/cgo/test/issue26213/jni.h delete mode 100644 libgo/misc/cgo/test/issue26213/test26213.go delete mode 100644 libgo/misc/cgo/test/issue26430.go delete mode 100644 libgo/misc/cgo/test/issue26430/a.go delete mode 100644 libgo/misc/cgo/test/issue26430/b.go delete mode 100644 libgo/misc/cgo/test/issue26517.go delete mode 100644 libgo/misc/cgo/test/issue26743.go delete mode 100644 libgo/misc/cgo/test/issue26743/a.go delete mode 100644 libgo/misc/cgo/test/issue26743/b.go delete mode 100644 libgo/misc/cgo/test/issue27054/egl.h delete mode 100644 libgo/misc/cgo/test/issue27054/test27054.go delete mode 100644 libgo/misc/cgo/test/issue27340.go delete mode 100644 libgo/misc/cgo/test/issue27340/a.go delete mode 100644 libgo/misc/cgo/test/issue28545.go delete mode 100644 libgo/misc/cgo/test/issue28772.go delete mode 100644 libgo/misc/cgo/test/issue28896.go delete mode 100644 libgo/misc/cgo/test/issue29383.go delete mode 100644 libgo/misc/cgo/test/issue29748.go delete mode 100644 libgo/misc/cgo/test/issue29781.go delete mode 100644 libgo/misc/cgo/test/issue30065.go delete mode 100644 libgo/misc/cgo/test/issue3250.go delete mode 100644 libgo/misc/cgo/test/issue3250w.go delete mode 100644 libgo/misc/cgo/test/issue3261.go delete mode 100644 libgo/misc/cgo/test/issue3729.go delete mode 100644 libgo/misc/cgo/test/issue3729w.go delete mode 100644 libgo/misc/cgo/test/issue3741.go delete mode 100644 libgo/misc/cgo/test/issue3775.go delete mode 100644 libgo/misc/cgo/test/issue3945.go delete mode 100644 libgo/misc/cgo/test/issue4054a.go delete mode 100644 libgo/misc/cgo/test/issue4054b.go delete mode 100644 libgo/misc/cgo/test/issue4339.go delete mode 100644 libgo/misc/cgo/test/issue4417.go delete mode 100644 libgo/misc/cgo/test/issue4857.go delete mode 100644 libgo/misc/cgo/test/issue5227.go delete mode 100644 libgo/misc/cgo/test/issue5242.go delete mode 100644 libgo/misc/cgo/test/issue5337.go delete mode 100644 libgo/misc/cgo/test/issue5337w.go delete mode 100644 libgo/misc/cgo/test/issue5548.go delete mode 100644 libgo/misc/cgo/test/issue5603.go delete mode 100644 libgo/misc/cgo/test/issue5740.go delete mode 100644 libgo/misc/cgo/test/issue5986.go delete mode 100644 libgo/misc/cgo/test/issue6128.go delete mode 100644 libgo/misc/cgo/test/issue6390.go delete mode 100644 libgo/misc/cgo/test/issue6472.go delete mode 100644 libgo/misc/cgo/test/issue6506.go delete mode 100644 libgo/misc/cgo/test/issue6612.go delete mode 100644 libgo/misc/cgo/test/issue6833.go delete mode 100644 libgo/misc/cgo/test/issue6907.go delete mode 100644 libgo/misc/cgo/test/issue6907export.go delete mode 100644 libgo/misc/cgo/test/issue7560.go delete mode 100644 libgo/misc/cgo/test/issue7665.go delete mode 100644 libgo/misc/cgo/test/issue7786.go delete mode 100644 libgo/misc/cgo/test/issue7978.go delete mode 100644 libgo/misc/cgo/test/issue8092.go delete mode 100644 libgo/misc/cgo/test/issue8331a.go delete mode 100644 libgo/misc/cgo/test/issue8331b.go delete mode 100644 libgo/misc/cgo/test/issue8428.go delete mode 100644 libgo/misc/cgo/test/issue8441.go delete mode 100644 libgo/misc/cgo/test/issue8756.go delete mode 100644 libgo/misc/cgo/test/issue8756/issue8756.go delete mode 100644 libgo/misc/cgo/test/issue8811.go delete mode 100644 libgo/misc/cgo/test/issue8828.go delete mode 100644 libgo/misc/cgo/test/issue8828/issue8828.c delete mode 100644 libgo/misc/cgo/test/issue8828/trivial.go delete mode 100644 libgo/misc/cgo/test/issue9026.go delete mode 100644 libgo/misc/cgo/test/issue9026/issue9026.go delete mode 100644 libgo/misc/cgo/test/issue9400/asm_386.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_amd64x.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_arm.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_arm64.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_mips64x.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_mipsx.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_ppc64x.s delete mode 100644 libgo/misc/cgo/test/issue9400/asm_s390x.s delete mode 100644 libgo/misc/cgo/test/issue9400/gccgo.go delete mode 100644 libgo/misc/cgo/test/issue9400/stubs.go delete mode 100644 libgo/misc/cgo/test/issue9400_linux.go delete mode 100644 libgo/misc/cgo/test/issue9510.go delete mode 100644 libgo/misc/cgo/test/issue9510a/a.go delete mode 100644 libgo/misc/cgo/test/issue9510b/b.go delete mode 100644 libgo/misc/cgo/test/issue9557.go create mode 100644 libgo/misc/cgo/test/overlaydir_test.go create mode 100644 libgo/misc/cgo/test/pkg_test.go create mode 100644 libgo/misc/cgo/test/test.go delete mode 100644 libgo/misc/cgo/test/test22906.go delete mode 100644 libgo/misc/cgo/test/test26213.go delete mode 100644 libgo/misc/cgo/test/test27660.go create mode 100644 libgo/misc/cgo/test/test_unix.go create mode 100644 libgo/misc/cgo/test/test_windows.go create mode 100644 libgo/misc/cgo/test/testdata/cgo_linux_test.go create mode 100644 libgo/misc/cgo/test/testdata/cgo_test.go create mode 100644 libgo/misc/cgo/test/testdata/gcc68255.go create mode 100644 libgo/misc/cgo/test/testdata/gcc68255/a.go create mode 100644 libgo/misc/cgo/test/testdata/gcc68255/c.c create mode 100644 libgo/misc/cgo/test/testdata/gcc68255/c.h create mode 100644 libgo/misc/cgo/test/testdata/issue20266.go create mode 100644 libgo/misc/cgo/test/testdata/issue20266/issue20266.h create mode 100644 libgo/misc/cgo/test/testdata/issue23555.go create mode 100644 libgo/misc/cgo/test/testdata/issue23555a/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue23555b/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161_darwin_test.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161arg/def.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161arg/use.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161e0/main.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161e1/main.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161e2/main.go create mode 100644 libgo/misc/cgo/test/testdata/issue24161res/restype.go create mode 100644 libgo/misc/cgo/test/testdata/issue26213/jni.h create mode 100644 libgo/misc/cgo/test/testdata/issue26213/test26213.go create mode 100644 libgo/misc/cgo/test/testdata/issue26430.go create mode 100644 libgo/misc/cgo/test/testdata/issue26430/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue26430/b.go create mode 100644 libgo/misc/cgo/test/testdata/issue26743.go create mode 100644 libgo/misc/cgo/test/testdata/issue26743/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue26743/b.go create mode 100644 libgo/misc/cgo/test/testdata/issue27054/egl.h create mode 100644 libgo/misc/cgo/test/testdata/issue27054/test27054.go create mode 100644 libgo/misc/cgo/test/testdata/issue27340.go create mode 100644 libgo/misc/cgo/test/testdata/issue27340/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue29563.go create mode 100644 libgo/misc/cgo/test/testdata/issue29563/weak.go create mode 100644 libgo/misc/cgo/test/testdata/issue29563/weak1.c create mode 100644 libgo/misc/cgo/test/testdata/issue29563/weak2.c create mode 100644 libgo/misc/cgo/test/testdata/issue8756.go create mode 100644 libgo/misc/cgo/test/testdata/issue8756/issue8756.go create mode 100644 libgo/misc/cgo/test/testdata/issue8828.go create mode 100644 libgo/misc/cgo/test/testdata/issue8828/issue8828.c create mode 100644 libgo/misc/cgo/test/testdata/issue8828/trivial.go create mode 100644 libgo/misc/cgo/test/testdata/issue9026.go create mode 100644 libgo/misc/cgo/test/testdata/issue9026/issue9026.go create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_386.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_amd64x.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_arm.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_arm64.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_mips64x.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_mipsx.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_ppc64x.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_s390x.s create mode 100644 libgo/misc/cgo/test/testdata/issue9400/gccgo.go create mode 100644 libgo/misc/cgo/test/testdata/issue9400/stubs.go create mode 100644 libgo/misc/cgo/test/testdata/issue9400_linux.go create mode 100644 libgo/misc/cgo/test/testdata/issue9510.go create mode 100644 libgo/misc/cgo/test/testdata/issue9510a/a.go create mode 100644 libgo/misc/cgo/test/testdata/issue9510b/b.go create mode 100644 libgo/misc/cgo/test/testdata/test26213.go create mode 100644 libgo/misc/cgo/test/testx.go delete mode 100644 libgo/misc/cgo/test/twoargs.go delete mode 100644 libgo/misc/cgo/testcarchive/main.c delete mode 100644 libgo/misc/cgo/testcarchive/main2.c delete mode 100644 libgo/misc/cgo/testcarchive/main3.c delete mode 100644 libgo/misc/cgo/testcarchive/main4.c delete mode 100644 libgo/misc/cgo/testcarchive/main5.c delete mode 100644 libgo/misc/cgo/testcarchive/main6.c delete mode 100644 libgo/misc/cgo/testcarchive/main_unix.c delete mode 100644 libgo/misc/cgo/testcarchive/main_windows.c create mode 100644 libgo/misc/cgo/testcarchive/overlaydir_test.go delete mode 100644 libgo/misc/cgo/testcarchive/src/libgo/libgo.go delete mode 100644 libgo/misc/cgo/testcarchive/src/libgo2/libgo2.go delete mode 100644 libgo/misc/cgo/testcarchive/src/libgo3/libgo3.go delete mode 100644 libgo/misc/cgo/testcarchive/src/libgo4/libgo4.go delete mode 100644 libgo/misc/cgo/testcarchive/src/libgo6/sigprof.go delete mode 100644 libgo/misc/cgo/testcarchive/src/p/p.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/libgo/libgo.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/libgo2/libgo2.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/libgo3/libgo3.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/libgo4/libgo4.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/libgo6/sigprof.go create mode 100644 libgo/misc/cgo/testcarchive/testdata/main.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main2.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main3.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main4.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main5.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main6.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main_unix.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/main_windows.c create mode 100644 libgo/misc/cgo/testcarchive/testdata/p/p.go delete mode 100644 libgo/misc/cgo/testcshared/main0.c delete mode 100644 libgo/misc/cgo/testcshared/main1.c delete mode 100644 libgo/misc/cgo/testcshared/main2.c delete mode 100644 libgo/misc/cgo/testcshared/main3.c delete mode 100644 libgo/misc/cgo/testcshared/main4.c delete mode 100644 libgo/misc/cgo/testcshared/main5.c create mode 100644 libgo/misc/cgo/testcshared/overlaydir_test.go delete mode 100644 libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go delete mode 100644 libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c delete mode 100644 libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go delete mode 100644 libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo/libgo.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo2/dup2.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo2/dup3.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo2/libgo2.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo4/libgo4.go delete mode 100644 libgo/misc/cgo/testcshared/src/libgo5/libgo5.go delete mode 100644 libgo/misc/cgo/testcshared/src/p/p.go create mode 100644 libgo/misc/cgo/testcshared/testdata/go2c2go/go/shlib.go create mode 100644 libgo/misc/cgo/testcshared/testdata/go2c2go/m1/c.c create mode 100644 libgo/misc/cgo/testcshared/testdata/go2c2go/m1/main.go create mode 100644 libgo/misc/cgo/testcshared/testdata/go2c2go/m2/main.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo/libgo.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo2/libgo2.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo4/libgo4.go create mode 100644 libgo/misc/cgo/testcshared/testdata/libgo5/libgo5.go create mode 100644 libgo/misc/cgo/testcshared/testdata/main0.c create mode 100644 libgo/misc/cgo/testcshared/testdata/main1.c create mode 100644 libgo/misc/cgo/testcshared/testdata/main2.c create mode 100644 libgo/misc/cgo/testcshared/testdata/main3.c create mode 100644 libgo/misc/cgo/testcshared/testdata/main4.c create mode 100644 libgo/misc/cgo/testcshared/testdata/main5.c create mode 100644 libgo/misc/cgo/testcshared/testdata/p/p.go delete mode 100644 libgo/misc/cgo/testgodefs/anonunion.go delete mode 100644 libgo/misc/cgo/testgodefs/fieldtypedef.go delete mode 100644 libgo/misc/cgo/testgodefs/issue8478.go delete mode 100644 libgo/misc/cgo/testgodefs/main.go create mode 100644 libgo/misc/cgo/testgodefs/testdata/anonunion.go create mode 100644 libgo/misc/cgo/testgodefs/testdata/fieldtypedef.go create mode 100644 libgo/misc/cgo/testgodefs/testdata/issue8478.go create mode 100644 libgo/misc/cgo/testgodefs/testdata/main.go delete mode 100644 libgo/misc/cgo/testplugin/altpath/src/common/common.go delete mode 100644 libgo/misc/cgo/testplugin/altpath/src/plugin-mismatch/main.go create mode 100644 libgo/misc/cgo/testplugin/altpath/testdata/common/common.go create mode 100644 libgo/misc/cgo/testplugin/altpath/testdata/plugin-mismatch/main.go create mode 100644 libgo/misc/cgo/testplugin/overlaydir_test.go create mode 100644 libgo/misc/cgo/testplugin/plugin_test.go delete mode 100644 libgo/misc/cgo/testplugin/src/checkdwarf/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/common/common.go delete mode 100644 libgo/misc/cgo/testplugin/src/host/host.go delete mode 100644 libgo/misc/cgo/testplugin/src/iface/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/iface_a/a.go delete mode 100644 libgo/misc/cgo/testplugin/src/iface_b/b.go delete mode 100644 libgo/misc/cgo/testplugin/src/iface_i/i.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue18584/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue18584/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue18676/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue18676/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue19418/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue19418/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue19529/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue19534/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue19534/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue22175/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue22175/plugin1.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue22175/plugin2.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue22295.pkg/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue22295.pkg/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue24351/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue24351/plugin.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue25756/main.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue25756/plugin/c-life.c delete mode 100644 libgo/misc/cgo/testplugin/src/issue25756/plugin/life.go delete mode 100644 libgo/misc/cgo/testplugin/src/issue25756/plugin/life.h delete mode 100644 libgo/misc/cgo/testplugin/src/plugin1/plugin1.go delete mode 100644 libgo/misc/cgo/testplugin/src/plugin2/plugin2.go delete mode 100644 libgo/misc/cgo/testplugin/src/sub/plugin1/plugin1.go delete mode 100644 libgo/misc/cgo/testplugin/test.bash create mode 100644 libgo/misc/cgo/testplugin/testdata/checkdwarf/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/common/common.go create mode 100644 libgo/misc/cgo/testplugin/testdata/host/host.go create mode 100644 libgo/misc/cgo/testplugin/testdata/iface/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/iface_a/a.go create mode 100644 libgo/misc/cgo/testplugin/testdata/iface_b/b.go create mode 100644 libgo/misc/cgo/testplugin/testdata/iface_i/i.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue18584/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue18584/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue18676/dynamodbstreamsevt/definition.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue18676/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue18676/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue19418/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue19418/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue19529/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue19534/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue19534/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue22175/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue22175/plugin1.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue22175/plugin2.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue22295.pkg/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue22295.pkg/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue24351/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue24351/plugin.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue25756/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue25756/plugin/c-life.c create mode 100644 libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.go create mode 100644 libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.h create mode 100644 libgo/misc/cgo/testplugin/testdata/plugin1/plugin1.go create mode 100644 libgo/misc/cgo/testplugin/testdata/plugin2/plugin2.go create mode 100644 libgo/misc/cgo/testplugin/testdata/sub/plugin1/plugin1.go create mode 100644 libgo/misc/cgo/testplugin/testdata/unnamed1/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/unnamed2/main.go delete mode 100644 libgo/misc/cgo/testplugin/unnamed1/main.go delete mode 100644 libgo/misc/cgo/testplugin/unnamed2/main.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan2.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan2_cmsan.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan3.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan4.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan5.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan6.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan_fail.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/msan_shared.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan10.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan11.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan12.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan2.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan3.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan4.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan5.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan6.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan7.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan8.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan9.go delete mode 100644 libgo/misc/cgo/testsanitizers/src/tsan_shared.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan2.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan2_cmsan.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan3.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan4.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan5.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan6.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan_fail.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan_shared.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan10.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan11.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan12.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan2.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan3.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan4.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan5.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan6.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan7.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan8.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan9.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/tsan_shared.go create mode 100644 libgo/misc/cgo/testshared/overlaydir_test.go delete mode 100644 libgo/misc/cgo/testshared/src/dep2/dep2.go delete mode 100644 libgo/misc/cgo/testshared/src/dep3/dep3.go delete mode 100644 libgo/misc/cgo/testshared/src/depBase/asm.s delete mode 100644 libgo/misc/cgo/testshared/src/depBase/dep.go delete mode 100644 libgo/misc/cgo/testshared/src/depBase/gccgo.go delete mode 100644 libgo/misc/cgo/testshared/src/depBase/stubs.go delete mode 100644 libgo/misc/cgo/testshared/src/division/division.go delete mode 100644 libgo/misc/cgo/testshared/src/exe/exe.go delete mode 100644 libgo/misc/cgo/testshared/src/exe2/exe2.go delete mode 100644 libgo/misc/cgo/testshared/src/exe3/exe3.go delete mode 100644 libgo/misc/cgo/testshared/src/execgo/exe.go delete mode 100644 libgo/misc/cgo/testshared/src/explicit/explicit.go delete mode 100644 libgo/misc/cgo/testshared/src/global/main.go delete mode 100644 libgo/misc/cgo/testshared/src/globallib/global.go delete mode 100644 libgo/misc/cgo/testshared/src/iface/main.go delete mode 100644 libgo/misc/cgo/testshared/src/iface_a/a.go delete mode 100644 libgo/misc/cgo/testshared/src/iface_b/b.go delete mode 100644 libgo/misc/cgo/testshared/src/iface_i/i.go delete mode 100644 libgo/misc/cgo/testshared/src/implicit/implicit.go delete mode 100644 libgo/misc/cgo/testshared/src/implicitcmd/implicitcmd.go delete mode 100644 libgo/misc/cgo/testshared/src/issue25065/a.go delete mode 100644 libgo/misc/cgo/testshared/src/trivial/trivial.go create mode 100644 libgo/misc/cgo/testshared/testdata/dep2/dep2.go create mode 100644 libgo/misc/cgo/testshared/testdata/dep3/dep3.go create mode 100644 libgo/misc/cgo/testshared/testdata/depBase/asm.s create mode 100644 libgo/misc/cgo/testshared/testdata/depBase/dep.go create mode 100644 libgo/misc/cgo/testshared/testdata/depBase/gccgo.go create mode 100644 libgo/misc/cgo/testshared/testdata/depBase/stubs.go create mode 100644 libgo/misc/cgo/testshared/testdata/division/division.go create mode 100644 libgo/misc/cgo/testshared/testdata/exe/exe.go create mode 100644 libgo/misc/cgo/testshared/testdata/exe2/exe2.go create mode 100644 libgo/misc/cgo/testshared/testdata/exe3/exe3.go create mode 100644 libgo/misc/cgo/testshared/testdata/execgo/exe.go create mode 100644 libgo/misc/cgo/testshared/testdata/explicit/explicit.go create mode 100644 libgo/misc/cgo/testshared/testdata/global/main.go create mode 100644 libgo/misc/cgo/testshared/testdata/globallib/global.go create mode 100644 libgo/misc/cgo/testshared/testdata/iface/main.go create mode 100644 libgo/misc/cgo/testshared/testdata/iface_a/a.go create mode 100644 libgo/misc/cgo/testshared/testdata/iface_b/b.go create mode 100644 libgo/misc/cgo/testshared/testdata/iface_i/i.go create mode 100644 libgo/misc/cgo/testshared/testdata/implicit/implicit.go create mode 100644 libgo/misc/cgo/testshared/testdata/implicitcmd/implicitcmd.go create mode 100644 libgo/misc/cgo/testshared/testdata/issue25065/a.go create mode 100644 libgo/misc/cgo/testshared/testdata/trivial/trivial.go delete mode 100644 libgo/misc/cgo/testso/cgoso.c delete mode 100644 libgo/misc/cgo/testso/cgoso.go delete mode 100644 libgo/misc/cgo/testso/cgoso_c.c delete mode 100644 libgo/misc/cgo/testso/cgoso_unix.go delete mode 100644 libgo/misc/cgo/testso/main.go create mode 100644 libgo/misc/cgo/testso/noso_test.go create mode 100644 libgo/misc/cgo/testso/overlaydir_test.go create mode 100644 libgo/misc/cgo/testso/so_test.go create mode 100644 libgo/misc/cgo/testso/testdata/cgoso.c create mode 100644 libgo/misc/cgo/testso/testdata/cgoso.go create mode 100644 libgo/misc/cgo/testso/testdata/cgoso_c.c create mode 100644 libgo/misc/cgo/testso/testdata/cgoso_unix.go create mode 100644 libgo/misc/cgo/testso/testdata/main.go delete mode 100644 libgo/misc/cgo/testsovar/cgoso.go delete mode 100644 libgo/misc/cgo/testsovar/cgoso_c.c delete mode 100644 libgo/misc/cgo/testsovar/cgoso_c.h delete mode 100644 libgo/misc/cgo/testsovar/main.go create mode 100644 libgo/misc/cgo/testsovar/noso_test.go create mode 100644 libgo/misc/cgo/testsovar/overlaydir_test.go create mode 100644 libgo/misc/cgo/testsovar/so_test.go create mode 100644 libgo/misc/cgo/testsovar/testdata/cgoso.go create mode 100644 libgo/misc/cgo/testsovar/testdata/cgoso_c.c create mode 100644 libgo/misc/cgo/testsovar/testdata/cgoso_c.h create mode 100644 libgo/misc/cgo/testsovar/testdata/main.go (limited to 'libgo/misc/cgo') diff --git a/libgo/misc/cgo/errors/errors_test.go b/libgo/misc/cgo/errors/errors_test.go index 59054f4..e6bac0f 100644 --- a/libgo/misc/cgo/errors/errors_test.go +++ b/libgo/misc/cgo/errors/errors_test.go @@ -18,7 +18,7 @@ import ( ) func path(file string) string { - return filepath.Join("src", file) + return filepath.Join("testdata", file) } func check(t *testing.T, file string) { @@ -63,7 +63,7 @@ func expect(t *testing.T, file string, errors []*regexp.Regexp) { defer os.RemoveAll(dir) dst := filepath.Join(dir, strings.TrimSuffix(file, ".go")) - cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted + cmd := exec.Command("go", "build", "-gcflags=-L -e", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted out, err := cmd.CombinedOutput() if err == nil { t.Errorf("expected cgo to fail but it succeeded") @@ -107,21 +107,10 @@ func TestReportsTypeErrors(t *testing.T) { for _, file := range []string{ "err1.go", "err2.go", - "err3.go", - "issue7757.go", - "issue8442.go", "issue11097a.go", "issue11097b.go", - "issue13129.go", - "issue13423.go", - "issue13467.go", - "issue13635.go", - "issue13830.go", - "issue16116.go", - "issue16591.go", "issue18452.go", "issue18889.go", - "issue26745.go", "issue28721.go", } { check(t, file) diff --git a/libgo/misc/cgo/errors/ptr_test.go b/libgo/misc/cgo/errors/ptr_test.go index 254671f..d1ef191 100644 --- a/libgo/misc/cgo/errors/ptr_test.go +++ b/libgo/misc/cgo/errors/ptr_test.go @@ -7,21 +7,25 @@ package errorstest import ( - "bufio" "bytes" + "flag" "fmt" "io/ioutil" "os" "os/exec" "path/filepath" "strings" + "sync/atomic" "testing" ) +var tmp = flag.String("tmp", "", "use `dir` for temporary files and do not clean up") + // ptrTest is the tests without the boilerplate. type ptrTest struct { name string // for reporting c string // the cgo comment + c1 string // cgo comment forced into non-export cgo file imports []string // a list of imports support string // supporting functions body string // the body of the main function @@ -39,253 +43,248 @@ var ptrTests = []ptrTest{ { // Passing a pointer to a struct that contains a Go pointer. name: "ptr1", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `C.f(&C.s{new(C.int)})`, + c: `typedef struct s1 { int *p; } s1; void f1(s1 *ps) {}`, + body: `C.f1(&C.s1{new(C.int)})`, fail: true, }, { // Passing a pointer to a struct that contains a Go pointer. name: "ptr2", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `p := &C.s{new(C.int)}; C.f(p)`, + c: `typedef struct s2 { int *p; } s2; void f2(s2 *ps) {}`, + body: `p := &C.s2{new(C.int)}; C.f2(p)`, fail: true, }, { // Passing a pointer to an int field of a Go struct // that (irrelevantly) contains a Go pointer. name: "ok1", - c: `struct s { int i; int *p; }; void f(int *p) {}`, - body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`, + c: `struct s3 { int i; int *p; }; void f3(int *p) {}`, + body: `p := &C.struct_s3{i: 0, p: new(C.int)}; C.f3(&p.i)`, fail: false, }, { // Passing a pointer to a pointer field of a Go struct. - name: "ptr-field", - c: `struct s { int i; int *p; }; void f(int **p) {}`, - body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`, + name: "ptrfield", + c: `struct s4 { int i; int *p; }; void f4(int **p) {}`, + body: `p := &C.struct_s4{i: 0, p: new(C.int)}; C.f4(&p.p)`, fail: true, }, { // Passing a pointer to a pointer field of a Go // struct, where the field does not contain a Go // pointer, but another field (irrelevantly) does. - name: "ptr-field-ok", - c: `struct s { int *p1; int *p2; }; void f(int **p) {}`, - body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`, + name: "ptrfieldok", + c: `struct s5 { int *p1; int *p2; }; void f5(int **p) {}`, + body: `p := &C.struct_s5{p1: nil, p2: new(C.int)}; C.f5(&p.p1)`, fail: false, }, { // Passing the address of a slice with no Go pointers. - name: "slice-ok-1", - c: `void f(void **p) {}`, + name: "sliceok1", + c: `void f6(void **p) {}`, imports: []string{"unsafe"}, - body: `s := []unsafe.Pointer{nil}; C.f(&s[0])`, + body: `s := []unsafe.Pointer{nil}; C.f6(&s[0])`, fail: false, }, { // Passing the address of a slice with a Go pointer. - name: "slice-ptr-1", - c: `void f(void **p) {}`, + name: "sliceptr1", + c: `void f7(void **p) {}`, imports: []string{"unsafe"}, - body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`, + body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f7(&s[0])`, fail: true, }, { // Passing the address of a slice with a Go pointer, // where we are passing the address of an element that // is not a Go pointer. - name: "slice-ptr-2", - c: `void f(void **p) {}`, + name: "sliceptr2", + c: `void f8(void **p) {}`, imports: []string{"unsafe"}, - body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`, + body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f8(&s[0])`, fail: true, }, { // Passing the address of a slice that is an element // in a struct only looks at the slice. - name: "slice-ok-2", - c: `void f(void **p) {}`, + name: "sliceok2", + c: `void f9(void **p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; s []unsafe.Pointer }`, - body: `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`, + support: `type S9 struct { p *int; s []unsafe.Pointer }`, + body: `i := 0; p := &S9{p:&i, s:[]unsafe.Pointer{nil}}; C.f9(&p.s[0])`, fail: false, }, { // Passing the address of a slice of an array that is // an element in a struct, with a type conversion. - name: "slice-ok-3", - c: `void f(void* p) {}`, + name: "sliceok3", + c: `void f10(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [4]byte }`, - body: `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`, + support: `type S10 struct { p *int; a [4]byte }`, + body: `i := 0; p := &S10{p:&i}; s := p.a[:]; C.f10(unsafe.Pointer(&s[0]))`, fail: false, }, { // Passing the address of a slice of an array that is // an element in a struct, with a type conversion. - name: "slice-ok-4", - c: `typedef void* PV; void f(PV p) {}`, + name: "sliceok4", + c: `typedef void* PV11; void f11(PV11 p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [4]byte }`, - body: `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`, + support: `type S11 struct { p *int; a [4]byte }`, + body: `i := 0; p := &S11{p:&i}; C.f11(C.PV11(unsafe.Pointer(&p.a[0])))`, fail: false, }, { // Passing the address of a static variable with no // pointers doesn't matter. name: "varok", - c: `void f(char** parg) {}`, - support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`, - body: `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`, + c: `void f12(char** parg) {}`, + support: `var hello12 = [...]C.char{'h', 'e', 'l', 'l', 'o'}`, + body: `parg := [1]*C.char{&hello12[0]}; C.f12(&parg[0])`, fail: false, }, { // Passing the address of a static variable with // pointers does matter. - name: "var", - c: `void f(char*** parg) {}`, - support: `var hello = [...]*C.char{new(C.char)}`, - body: `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`, + name: "var1", + c: `void f13(char*** parg) {}`, + support: `var hello13 = [...]*C.char{new(C.char)}`, + body: `parg := [1]**C.char{&hello13[0]}; C.f13(&parg[0])`, fail: true, }, { // Storing a Go pointer into C memory should fail. name: "barrier", c: `#include - char **f1() { return malloc(sizeof(char*)); } - void f2(char **p) {}`, - body: `p := C.f1(); *p = new(C.char); C.f2(p)`, + char **f14a() { return malloc(sizeof(char*)); } + void f14b(char **p) {}`, + body: `p := C.f14a(); *p = new(C.char); C.f14b(p)`, fail: true, expensive: true, }, { // Storing a Go pointer into C memory by assigning a // large value should fail. - name: "barrier-struct", + name: "barrierstruct", c: `#include - struct s { char *a[10]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`, + struct s15 { char *a[10]; }; + struct s15 *f15() { return malloc(sizeof(struct s15)); } + void f15b(struct s15 *p) {}`, + body: `p := C.f15(); p.a = [10]*C.char{new(C.char)}; C.f15b(p)`, fail: true, expensive: true, }, { // Storing a Go pointer into C memory using a slice // copy should fail. - name: "barrier-slice", + name: "barrierslice", c: `#include - struct s { char *a[10]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`, + struct s16 { char *a[10]; }; + struct s16 *f16() { return malloc(sizeof(struct s16)); } + void f16b(struct s16 *p) {}`, + body: `p := C.f16(); copy(p.a[:], []*C.char{new(C.char)}); C.f16b(p)`, fail: true, expensive: true, }, { // A very large value uses a GC program, which is a // different code path. - name: "barrier-gcprog-array", + name: "barriergcprogarray", c: `#include - struct s { char *a[32769]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {}`, - body: `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`, + struct s17 { char *a[32769]; }; + struct s17 *f17() { return malloc(sizeof(struct s17)); } + void f17b(struct s17 *p) {}`, + body: `p := C.f17(); p.a = [32769]*C.char{new(C.char)}; C.f17b(p)`, fail: true, expensive: true, }, { // Similar case, with a source on the heap. - name: "barrier-gcprog-array-heap", + name: "barriergcprogarrayheap", c: `#include - struct s { char *a[32769]; }; - struct s *f1() { return malloc(sizeof(struct s)); } - void f2(struct s *p) {} - void f3(void *p) {}`, + struct s18 { char *a[32769]; }; + struct s18 *f18() { return malloc(sizeof(struct s18)); } + void f18b(struct s18 *p) {} + void f18c(void *p) {}`, imports: []string{"unsafe"}, - body: `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`, + body: `p := C.f18(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f18b(p); n[0] = nil; C.f18c(unsafe.Pointer(n))`, fail: true, expensive: true, }, { // A GC program with a struct. - name: "barrier-gcprog-struct", + name: "barriergcprogstruct", c: `#include - struct s { char *a[32769]; }; - struct s2 { struct s f; }; - struct s2 *f1() { return malloc(sizeof(struct s2)); } - void f2(struct s2 *p) {}`, - body: `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`, + struct s19a { char *a[32769]; }; + struct s19b { struct s19a f; }; + struct s19b *f19() { return malloc(sizeof(struct s19b)); } + void f19b(struct s19b *p) {}`, + body: `p := C.f19(); p.f = C.struct_s19a{[32769]*C.char{new(C.char)}}; C.f19b(p)`, fail: true, expensive: true, }, { // Similar case, with a source on the heap. - name: "barrier-gcprog-struct-heap", + name: "barriergcprogstructheap", c: `#include - struct s { char *a[32769]; }; - struct s2 { struct s f; }; - struct s2 *f1() { return malloc(sizeof(struct s2)); } - void f2(struct s2 *p) {} - void f3(void *p) {}`, + struct s20a { char *a[32769]; }; + struct s20b { struct s20a f; }; + struct s20b *f20() { return malloc(sizeof(struct s20b)); } + void f20b(struct s20b *p) {} + void f20c(void *p) {}`, imports: []string{"unsafe"}, - body: `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`, + body: `p := C.f20(); n := &C.struct_s20a{[32769]*C.char{new(C.char)}}; p.f = *n; C.f20b(p); n.a[0] = nil; C.f20c(unsafe.Pointer(n))`, fail: true, expensive: true, }, { // Exported functions may not return Go pointers. name: "export1", - c: `extern unsigned char *GoFn();`, - support: `//export GoFn - func GoFn() *byte { return new(byte) }`, - body: `C.GoFn()`, + c: `extern unsigned char *GoFn21();`, + support: `//export GoFn21 + func GoFn21() *byte { return new(byte) }`, + body: `C.GoFn21()`, fail: true, }, { // Returning a C pointer is fine. name: "exportok", c: `#include - extern unsigned char *GoFn();`, - support: `//export GoFn - func GoFn() *byte { return (*byte)(C.malloc(1)) }`, - body: `C.GoFn()`, + extern unsigned char *GoFn22();`, + support: `//export GoFn22 + func GoFn22() *byte { return (*byte)(C.malloc(1)) }`, + body: `C.GoFn22()`, }, { // Passing a Go string is fine. - name: "pass-string", + name: "passstring", c: `#include - typedef struct { const char *p; ptrdiff_t n; } gostring; - gostring f(gostring s) { return s; }`, + typedef struct { const char *p; ptrdiff_t n; } gostring23; + gostring23 f23(gostring23 s) { return s; }`, imports: []string{"unsafe"}, - body: `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`, + body: `s := "a"; r := C.f23(*(*C.gostring23)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`, }, { // Passing a slice of Go strings fails. - name: "pass-string-slice", - c: `void f(void *p) {}`, + name: "passstringslice", + c: `void f24(void *p) {}`, imports: []string{"strings", "unsafe"}, - support: `type S struct { a [1]string }`, - body: `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`, + support: `type S24 struct { a [1]string }`, + body: `s := S24{a:[1]string{strings.Repeat("a", 2)}}; C.f24(unsafe.Pointer(&s.a[0]))`, fail: true, }, { // Exported functions may not return strings. - name: "ret-string", - c: `extern void f();`, + name: "retstring", + c: `extern void f25();`, imports: []string{"strings"}, - support: `//export GoStr - func GoStr() string { return strings.Repeat("a", 2) }`, - body: `C.f()`, - extra: []extra{ - { - "call.c", - `#include - typedef struct { const char *p; ptrdiff_t n; } gostring; - extern gostring GoStr(); - void f() { GoStr(); }`, - }, - }, + support: `//export GoStr25 + func GoStr25() string { return strings.Repeat("a", 2) }`, + body: `C.f25()`, + c1: `#include + typedef struct { const char *p; ptrdiff_t n; } gostring25; + extern gostring25 GoStr25(); + void f25() { GoStr25(); }`, fail: true, }, { @@ -296,37 +295,37 @@ var ptrTests = []ptrTest{ // that is, we are testing something that is not unsafe. name: "ptrdata1", c: `#include - void f(void* p) {}`, + void f26(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [8*8]byte; u uintptr }`, - body: `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`, + support: `type S26 struct { p *int; a [8*8]byte; u uintptr }`, + body: `i := 0; p := &S26{u:uintptr(unsafe.Pointer(&i))}; q := (*S26)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f26(unsafe.Pointer(q))`, fail: false, }, { // Like ptrdata1, but with a type that uses a GC program. name: "ptrdata2", c: `#include - void f(void* p) {}`, + void f27(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`, - body: `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`, + support: `type S27 struct { p *int; a [32769*8]byte; q *int; u uintptr }`, + body: `i := 0; p := S27{u:uintptr(unsafe.Pointer(&i))}; q := (*S27)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f27(unsafe.Pointer(q))`, fail: false, }, { // Check deferred pointers when they are used, not // when the defer statement is run. - name: "defer", - c: `typedef struct s { int *p; } s; void f(s *ps) {}`, - body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`, + name: "defer1", + c: `typedef struct s28 { int *p; } s28; void f28(s28 *ps) {}`, + body: `p := &C.s28{}; defer C.f28(p); p.p = new(C.int)`, fail: true, }, { // Check a pointer to a union if the union has any // pointer fields. name: "union1", - c: `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`, + c: `typedef union { char **p; unsigned long i; } u29; void f29(u29 *pu) {}`, imports: []string{"unsafe"}, - body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`, + body: `var b C.char; p := &b; C.f29((*C.u29)(unsafe.Pointer(&p)))`, fail: true, }, { @@ -336,55 +335,55 @@ var ptrTests = []ptrTest{ // integer that happens to have the same // representation as a pointer. name: "union2", - c: `typedef union { unsigned long i; } u; void f(u *pu) {}`, + c: `typedef union { unsigned long i; } u39; void f39(u39 *pu) {}`, imports: []string{"unsafe"}, - body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`, + body: `var b C.char; p := &b; C.f39((*C.u39)(unsafe.Pointer(&p)))`, fail: false, }, { // Test preemption while entering a cgo call. Issue #21306. - name: "preempt-during-call", - c: `void f() {}`, + name: "preemptduringcall", + c: `void f30() {}`, imports: []string{"runtime", "sync"}, - body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`, + body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f30(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`, fail: false, }, { // Test poller deadline with cgocheck=2. Issue #23435. name: "deadline", - c: `#define US 10`, + c: `#define US31 10`, imports: []string{"os", "time"}, - body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`, + body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US31 * time.Microsecond))`, fail: false, }, { // Test for double evaluation of channel receive. - name: "chan-recv", - c: `void f(char** p) {}`, + name: "chanrecv", + c: `void f32(char** p) {}`, imports: []string{"time"}, - body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f(&(<-c)[0]);`, + body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f32(&(<-c)[0]);`, fail: false, }, { // Test that converting the address of a struct field // to unsafe.Pointer still just checks that field. // Issue #25941. - name: "struct-field", - c: `void f(void* p) {}`, + name: "structfield", + c: `void f33(void* p) {}`, imports: []string{"unsafe"}, - support: `type S struct { p *int; a [8]byte; u uintptr }`, - body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a))`, + support: `type S33 struct { p *int; a [8]byte; u uintptr }`, + body: `s := &S33{p: new(int)}; C.f33(unsafe.Pointer(&s.a))`, fail: false, }, { // Test that converting multiple struct field // addresses to unsafe.Pointer still just checks those // fields. Issue #25941. - name: "struct-field-2", - c: `void f(void* p, int r, void* s) {}`, + name: "structfield2", + c: `void f34(void* p, int r, void* s) {}`, imports: []string{"unsafe"}, - support: `type S struct { a [8]byte; p *int; b int64; }`, - body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`, + support: `type S34 struct { a [8]byte; p *int; b int64; }`, + body: `s := &S34{p: new(int)}; C.f34(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`, fail: false, }, { @@ -392,18 +391,18 @@ var ptrTests = []ptrTest{ // evaluated when a deferred function is deferred, not // when it is run. name: "defer2", - c: `void f(char **pc) {}`, - support: `type S1 struct { s []*C.char }; type S2 struct { ps *S1 }`, - body: `p := &S2{&S1{[]*C.char{nil}}}; defer C.f(&p.ps.s[0]); p.ps = nil`, + c: `void f35(char **pc) {}`, + support: `type S35a struct { s []*C.char }; type S35b struct { ps *S35a }`, + body: `p := &S35b{&S35a{[]*C.char{nil}}}; defer C.f35(&p.ps.s[0]); p.ps = nil`, fail: false, }, { // Test that indexing into a function call still // examines only the slice being indexed. name: "buffer", - c: `void f(void *p) {}`, + c: `void f36(void *p) {}`, imports: []string{"bytes", "unsafe"}, - body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`, + body: `var b bytes.Buffer; b.WriteString("a"); C.f36(unsafe.Pointer(&b.Bytes()[0]))`, fail: false, }, { @@ -411,8 +410,8 @@ var ptrTests = []ptrTest{ name: "finalizer", c: `// Nothing to declare.`, imports: []string{"os"}, - support: `func open() { os.Open(os.Args[0]) }; var G [][]byte`, - body: `for i := 0; i < 10000; i++ { G = append(G, make([]byte, 4096)); if i % 100 == 0 { G = nil; open() } }`, + support: `func open37() { os.Open(os.Args[0]) }; var G37 [][]byte`, + body: `for i := 0; i < 10000; i++ { G37 = append(G37, make([]byte, 4096)); if i % 100 == 0 { G37 = nil; open37() } }`, fail: false, }, { @@ -420,98 +419,159 @@ var ptrTests = []ptrTest{ name: "structof", c: `// Nothing to declare.`, imports: []string{"reflect"}, - support: `type MyInt int; func (i MyInt) Get() int { return int(i) }; type Getter interface { Get() int }`, - body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt", Type: reflect.TypeOf(MyInt(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter).Get()`, + support: `type MyInt38 int; func (i MyInt38) Get() int { return int(i) }; type Getter38 interface { Get() int }`, + body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt38", Type: reflect.TypeOf(MyInt38(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter38).Get()`, fail: false, }, } func TestPointerChecks(t *testing.T) { + dir, exe := buildPtrTests(t) + + // We (TestPointerChecks) return before the parallel subtest functions do, + // so we can't just defer os.RemoveAll(dir). Instead we have to wait for + // the parallel subtests to finish. This code looks racy but is not: + // the add +1 run in serial before testOne blocks. The -1 run in parallel + // after testOne finishes. + var pending int32 for _, pt := range ptrTests { pt := pt t.Run(pt.name, func(t *testing.T) { - testOne(t, pt) + atomic.AddInt32(&pending, +1) + defer func() { + if atomic.AddInt32(&pending, -1) == 0 { + os.RemoveAll(dir) + } + }() + testOne(t, pt, exe) }) } } -func testOne(t *testing.T, pt ptrTest) { - t.Parallel() - - gopath, err := ioutil.TempDir("", filepath.Base(t.Name())) - if err != nil { - t.Fatal(err) +func buildPtrTests(t *testing.T) (dir, exe string) { + var gopath string + if *tmp != "" { + gopath = *tmp + dir = "" + } else { + d, err := ioutil.TempDir("", filepath.Base(t.Name())) + if err != nil { + t.Fatal(err) + } + dir = d + gopath = d } - defer os.RemoveAll(gopath) - src := filepath.Join(gopath, "src") - if err := os.Mkdir(src, 0777); err != nil { + src := filepath.Join(gopath, "src", "ptrtest") + if err := os.MkdirAll(src, 0777); err != nil { t.Fatal(err) } - name := filepath.Join(src, fmt.Sprintf("%s.go", filepath.Base(t.Name()))) - f, err := os.Create(name) - if err != nil { - t.Fatal(err) - } + // Prepare two cgo inputs: one for standard cgo and one for //export cgo. + // (The latter cannot have C definitions, only declarations.) + var cgo1, cgo2 bytes.Buffer + fmt.Fprintf(&cgo1, "package main\n\n/*\n") + fmt.Fprintf(&cgo2, "package main\n\n/*\n") - b := bufio.NewWriter(f) - fmt.Fprintln(b, `package main`) - fmt.Fprintln(b) - fmt.Fprintln(b, `/*`) - fmt.Fprintln(b, pt.c) - fmt.Fprintln(b, `*/`) - fmt.Fprintln(b, `import "C"`) - fmt.Fprintln(b) - for _, imp := range pt.imports { - fmt.Fprintln(b, `import "`+imp+`"`) - } - if len(pt.imports) > 0 { - fmt.Fprintln(b) - } - if len(pt.support) > 0 { - fmt.Fprintln(b, pt.support) - fmt.Fprintln(b) + // C code + for _, pt := range ptrTests { + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + cgo = &cgo2 + } + fmt.Fprintf(cgo, "%s\n", pt.c) + fmt.Fprintf(&cgo1, "%s\n", pt.c1) } - fmt.Fprintln(b, `func main() {`) - fmt.Fprintln(b, pt.body) - fmt.Fprintln(b, `}`) + fmt.Fprintf(&cgo1, "*/\nimport \"C\"\n\n") + fmt.Fprintf(&cgo2, "*/\nimport \"C\"\n\n") - if err := b.Flush(); err != nil { - t.Fatalf("flushing %s: %v", name, err) - } - if err := f.Close(); err != nil { - t.Fatalf("closing %s: %v", name, err) + // Imports + did1 := make(map[string]bool) + did2 := make(map[string]bool) + did1["os"] = true // for ptrTestMain + fmt.Fprintf(&cgo1, "import \"os\"\n") + + for _, pt := range ptrTests { + did := did1 + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + did = did2 + cgo = &cgo2 + } + for _, imp := range pt.imports { + if !did[imp] { + did[imp] = true + fmt.Fprintf(cgo, "import %q\n", imp) + } + } } - for _, e := range pt.extra { - if err := ioutil.WriteFile(filepath.Join(src, e.name), []byte(e.contents), 0644); err != nil { - t.Fatalf("writing %s: %v", e.name, err) + // Func support and bodies. + for _, pt := range ptrTests { + cgo := &cgo1 + if strings.Contains(pt.support, "//export") { + cgo = &cgo2 } + fmt.Fprintf(cgo, "%s\nfunc %s() {\n%s\n}\n", pt.support, pt.name, pt.body) } - args := func(cmd *exec.Cmd) string { - return strings.Join(cmd.Args, " ") + // Func list and main dispatch. + fmt.Fprintf(&cgo1, "var funcs = map[string]func() {\n") + for _, pt := range ptrTests { + fmt.Fprintf(&cgo1, "\t%q: %s,\n", pt.name, pt.name) } + fmt.Fprintf(&cgo1, "}\n\n") + fmt.Fprintf(&cgo1, "%s\n", ptrTestMain) - cmd := exec.Command("go", "build") + if err := ioutil.WriteFile(filepath.Join(src, "cgo1.go"), cgo1.Bytes(), 0666); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(src, "cgo2.go"), cgo2.Bytes(), 0666); err != nil { + t.Fatal(err) + } + + cmd := exec.Command("go", "build", "-o", "ptrtest.exe") cmd.Dir = src cmd.Env = append(os.Environ(), "GOPATH="+gopath) - buf, err := cmd.CombinedOutput() + out, err := cmd.CombinedOutput() if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) - t.Fatalf("failed to build: %v", err) + t.Fatalf("go build: %v\n%s", err, out) } - exe := filepath.Join(src, filepath.Base(src)) - cmd = exec.Command(exe) - cmd.Dir = src + return dir, filepath.Join(src, "ptrtest.exe") +} + +const ptrTestMain = ` +func main() { + for _, arg := range os.Args[1:] { + f := funcs[arg] + if f == nil { + panic("missing func "+arg) + } + f() + } +} +` + +var csem = make(chan bool, 16) + +func testOne(t *testing.T, pt ptrTest, exe string) { + t.Parallel() + + // Run the tests in parallel, but don't run too many + // executions in parallel, to avoid overloading the system. + runcmd := func(cgocheck string) ([]byte, error) { + csem <- true + defer func() { <-csem }() + cmd := exec.Command(exe, pt.name) + cmd.Env = append(os.Environ(), "GODEBUG=cgocheck="+cgocheck) + return cmd.CombinedOutput() + } if pt.expensive { - cmd.Env = cgocheckEnv("1") - buf, err := cmd.CombinedOutput() + buf, err := runcmd("1") if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) if pt.fail { t.Fatalf("test marked expensive, but failed when not expensive: %v", err) } else { @@ -519,54 +579,43 @@ func testOne(t *testing.T, pt ptrTest) { } } - cmd = exec.Command(exe) - cmd.Dir = src } + cgocheck := "" if pt.expensive { - cmd.Env = cgocheckEnv("2") + cgocheck = "2" } - buf, err = cmd.CombinedOutput() + buf, err := runcmd(cgocheck) if pt.fail { if err == nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("did not fail as expected") } else if !bytes.Contains(buf, []byte("Go pointer")) { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("did not print expected error (failed with %v)", err) } } else { if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly: %v", err) } if !pt.expensive { // Make sure it passes with the expensive checks. - cmd := exec.Command(exe) - cmd.Dir = src - cmd.Env = cgocheckEnv("2") - buf, err := cmd.CombinedOutput() + buf, err := runcmd("2") if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly with expensive checks: %v", err) } } } if pt.fail { - cmd = exec.Command(exe) - cmd.Dir = src - cmd.Env = cgocheckEnv("0") - buf, err := cmd.CombinedOutput() + buf, err := runcmd("0") if err != nil { - t.Logf("%#q:\n%s", args(cmd), buf) + t.Logf("%s", buf) t.Fatalf("failed unexpectedly with GODEBUG=cgocheck=0: %v", err) } } } - -func cgocheckEnv(val string) []string { - return append(os.Environ(), "GODEBUG=cgocheck="+val) -} diff --git a/libgo/misc/cgo/errors/src/err1.go b/libgo/misc/cgo/errors/src/err1.go deleted file mode 100644 index 2c232cf..0000000 --- a/libgo/misc/cgo/errors/src/err1.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#cgo LDFLAGS: -L/nonexist - -void test() { - xxx; // ERROR HERE -} -*/ -import "C" - -func main() { - C.test() -} diff --git a/libgo/misc/cgo/errors/src/err2.go b/libgo/misc/cgo/errors/src/err2.go deleted file mode 100644 index 3ab410b..0000000 --- a/libgo/misc/cgo/errors/src/err2.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -func main() { - s := "" - _ = s - C.malloc(s) // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/err3.go b/libgo/misc/cgo/errors/src/err3.go deleted file mode 100644 index 609e1a0..0000000 --- a/libgo/misc/cgo/errors/src/err3.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -typedef struct foo foo_t; -typedef struct bar bar_t; - -foo_t *foop; -*/ -import "C" - -func main() { - x := (*C.bar_t)(nil) - C.foop = x // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/err4.go b/libgo/misc/cgo/errors/src/err4.go deleted file mode 100644 index 8e5f78e..0000000 --- a/libgo/misc/cgo/errors/src/err4.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -long double x = 0; -*/ -import "C" - -func main() { - _ = C.x // ERROR HERE - _ = C.x -} diff --git a/libgo/misc/cgo/errors/src/issue11097a.go b/libgo/misc/cgo/errors/src/issue11097a.go deleted file mode 100644 index 028d10c..0000000 --- a/libgo/misc/cgo/errors/src/issue11097a.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -//enum test { foo, bar }; -*/ -import "C" - -func main() { - var a = C.enum_test(1) // ERROR HERE - _ = a -} diff --git a/libgo/misc/cgo/errors/src/issue11097b.go b/libgo/misc/cgo/errors/src/issue11097b.go deleted file mode 100644 index b00f24f..0000000 --- a/libgo/misc/cgo/errors/src/issue11097b.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -//enum test { foo, bar }; -*/ -import "C" - -func main() { - p := new(C.enum_test) // ERROR HERE - _ = p -} diff --git a/libgo/misc/cgo/errors/src/issue13129.go b/libgo/misc/cgo/errors/src/issue13129.go deleted file mode 100644 index 057bce4..0000000 --- a/libgo/misc/cgo/errors/src/issue13129.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// issue 13129: used to output error about C.unsignedshort with CC=clang - -package main - -import "C" - -func main() { - var x C.ushort - x = int(0) // ERROR HERE: C\.ushort -} diff --git a/libgo/misc/cgo/errors/src/issue13423.go b/libgo/misc/cgo/errors/src/issue13423.go deleted file mode 100644 index fc19157..0000000 --- a/libgo/misc/cgo/errors/src/issue13423.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// #include -import "C" - -func main() { - _ = C.fopen() // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue13467.go b/libgo/misc/cgo/errors/src/issue13467.go deleted file mode 100644 index e061880..0000000 --- a/libgo/misc/cgo/errors/src/issue13467.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package p - -/* -static int transform(int x) { return x; } -*/ -import "C" - -func F() { - var x rune = '✈' - var _ rune = C.transform(x) // ERROR HERE: C\.int -} diff --git a/libgo/misc/cgo/errors/src/issue13635.go b/libgo/misc/cgo/errors/src/issue13635.go deleted file mode 100644 index 3f38f5d..0000000 --- a/libgo/misc/cgo/errors/src/issue13635.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// issue 13635: used to output error about C.unsignedchar. -// This test tests all such types. - -package pkg - -import "C" - -func main() { - var ( - _ C.uchar = "uc" // ERROR HERE: C\.uchar - _ C.schar = "sc" // ERROR HERE: C\.schar - _ C.ushort = "us" // ERROR HERE: C\.ushort - _ C.uint = "ui" // ERROR HERE: C\.uint - _ C.ulong = "ul" // ERROR HERE: C\.ulong - _ C.longlong = "ll" // ERROR HERE: C\.longlong - _ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong - _ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat - _ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble - ) -} diff --git a/libgo/misc/cgo/errors/src/issue13830.go b/libgo/misc/cgo/errors/src/issue13830.go deleted file mode 100644 index ac20c82..0000000 --- a/libgo/misc/cgo/errors/src/issue13830.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo converts C void* to Go unsafe.Pointer, so despite appearances C -// void** is Go *unsafe.Pointer. This test verifies that we detect the -// problem at build time. - -package main - -// typedef void v; -// void F(v** p) {} -import "C" - -import "unsafe" - -type v [0]byte - -func f(p **v) { - C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE -} - -func main() { - var p *v - f(&p) -} diff --git a/libgo/misc/cgo/errors/src/issue14669.go b/libgo/misc/cgo/errors/src/issue14669.go deleted file mode 100644 index 04d2bcb..0000000 --- a/libgo/misc/cgo/errors/src/issue14669.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 14669: test that fails when build with CGO_CFLAGS selecting -// optimization. - -package p - -/* -const int E = 1; - -typedef struct s { - int c; -} s; -*/ -import "C" - -func F() { - _ = C.s{ - c: C.E, - } -} diff --git a/libgo/misc/cgo/errors/src/issue16116.go b/libgo/misc/cgo/errors/src/issue16116.go deleted file mode 100644 index 1e01cab..0000000 --- a/libgo/misc/cgo/errors/src/issue16116.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// void f(void *p, int x) {} -import "C" - -func main() { - _ = C.f(1) // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue16591.go b/libgo/misc/cgo/errors/src/issue16591.go deleted file mode 100644 index 10eb840..0000000 --- a/libgo/misc/cgo/errors/src/issue16591.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 16591: Test that we detect an invalid call that was being -// hidden by a type conversion inserted by cgo checking. - -package p - -// void f(int** p) { } -import "C" - -type x *C.int - -func F(p *x) { - C.f(p) // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue18452.go b/libgo/misc/cgo/errors/src/issue18452.go deleted file mode 100644 index 0386d76..0000000 --- a/libgo/misc/cgo/errors/src/issue18452.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 18452: show pos info in undefined name errors - -package p - -import ( - "C" - "fmt" -) - -func a() { - fmt.Println("Hello, world!") - C.function_that_does_not_exist() // ERROR HERE - C.pi // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue18889.go b/libgo/misc/cgo/errors/src/issue18889.go deleted file mode 100644 index bba6b8f..0000000 --- a/libgo/misc/cgo/errors/src/issue18889.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "C" - -func main() { - _ = C.malloc // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue26745.go b/libgo/misc/cgo/errors/src/issue26745.go deleted file mode 100644 index 0e22453..0000000 --- a/libgo/misc/cgo/errors/src/issue26745.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// int a; -// void CF(int i) {} -import "C" - -func F1(i int) int { - return C.a + 1 // ERROR HERE: :13 -} - -func F2(i int) { - C.CF(i) // ERROR HERE: :6 -} diff --git a/libgo/misc/cgo/errors/src/issue28069.go b/libgo/misc/cgo/errors/src/issue28069.go deleted file mode 100644 index e19a3b4..0000000 --- a/libgo/misc/cgo/errors/src/issue28069.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that the error message for an unrepresentable typedef in a -// union appears on the right line. This test is only run if the size -// of long double is larger than 64. - -package main - -/* -typedef long double Float128; - -typedef struct SV { - union { - Float128 float128; - } value; -} SV; -*/ -import "C" - -type ts struct { - tv *C.SV // ERROR HERE -} - -func main() {} diff --git a/libgo/misc/cgo/errors/src/issue28721.go b/libgo/misc/cgo/errors/src/issue28721.go deleted file mode 100644 index 0eb2a92..0000000 --- a/libgo/misc/cgo/errors/src/issue28721.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo should reject the use of mangled C names. - -package main - -/* -typedef struct a { - int i; -} a; -void fn(void) {} -*/ -import "C" - -type B _Ctype_struct_a // ERROR HERE - -var a _Ctype_struct_a // ERROR HERE - -type A struct { - a *_Ctype_struct_a // ERROR HERE -} - -var notExist _Ctype_NotExist // ERROR HERE - -func main() { - _Cfunc_fn() // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue7757.go b/libgo/misc/cgo/errors/src/issue7757.go deleted file mode 100644 index 0426e9f..0000000 --- a/libgo/misc/cgo/errors/src/issue7757.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -void foo() {} -*/ -import "C" - -func main() { - C.foo = C.foo // ERROR HERE -} diff --git a/libgo/misc/cgo/errors/src/issue8442.go b/libgo/misc/cgo/errors/src/issue8442.go deleted file mode 100644 index 60477ad..0000000 --- a/libgo/misc/cgo/errors/src/issue8442.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Issue 8442. Cgo output unhelpful error messages for -// invalid C preambles. - -/* -void issue8442foo(UNDEF*); // ERROR HERE -*/ -import "C" - -func main() { - C.issue8442foo(nil) -} diff --git a/libgo/misc/cgo/errors/src/long_double_size.go b/libgo/misc/cgo/errors/src/long_double_size.go deleted file mode 100644 index 8b797f8..0000000 --- a/libgo/misc/cgo/errors/src/long_double_size.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -const int sizeofLongDouble = sizeof(long double); -*/ -import "C" - -import "fmt" - -func main() { - fmt.Println(C.sizeofLongDouble) -} diff --git a/libgo/misc/cgo/errors/src/malloc.go b/libgo/misc/cgo/errors/src/malloc.go deleted file mode 100644 index 65da0208..0000000 --- a/libgo/misc/cgo/errors/src/malloc.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that C.malloc does not return nil. - -package main - -// #include -import "C" - -import ( - "fmt" - "runtime" -) - -func main() { - var size C.size_t - size-- - - // The Dragonfly libc succeeds when asked to allocate - // 0xffffffffffffffff bytes, so pass a different value that - // causes it to fail. - if runtime.GOOS == "dragonfly" { - size = C.size_t(0x7fffffff << (32 * (^uintptr(0) >> 63))) - } - - p := C.malloc(size) - if p == nil { - fmt.Println("malloc: C.malloc returned nil") - // Just exit normally--the test script expects this - // program to crash, so exiting normally indicates failure. - } -} diff --git a/libgo/misc/cgo/errors/testdata/err1.go b/libgo/misc/cgo/errors/testdata/err1.go new file mode 100644 index 0000000..ced7443 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/err1.go @@ -0,0 +1,22 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#cgo LDFLAGS: -L/nonexist + +void test() { + xxx; // ERROR HERE +} + +// Issue 8442. Cgo output unhelpful error messages for +// invalid C preambles. +void issue8442foo(UNDEF*); // ERROR HERE +*/ +import "C" + +func main() { + C.test() +} diff --git a/libgo/misc/cgo/errors/testdata/err2.go b/libgo/misc/cgo/errors/testdata/err2.go new file mode 100644 index 0000000..1d22401 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/err2.go @@ -0,0 +1,102 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include + +typedef struct foo foo_t; +typedef struct bar bar_t; + +foo_t *foop; + +long double x = 0; + +static int transform(int x) { return x; } + +typedef void v; +void F(v** p) {} + +void fvi(void *p, int x) {} + +void fppi(int** p) {} + +int i; +void fi(int i) {} +*/ +import "C" +import ( + "unsafe" +) + +func main() { + s := "" + _ = s + C.malloc(s) // ERROR HERE + + x := (*C.bar_t)(nil) + C.foop = x // ERROR HERE + + // issue 13129: used to output error about C.unsignedshort with CC=clang + var x C.ushort + x = int(0) // ERROR HERE: C\.ushort + + // issue 13423 + _ = C.fopen() // ERROR HERE + + // issue 13467 + var x rune = '✈' + var _ rune = C.transform(x) // ERROR HERE: C\.int + + // issue 13635: used to output error about C.unsignedchar. + // This test tests all such types. + var ( + _ C.uchar = "uc" // ERROR HERE: C\.uchar + _ C.schar = "sc" // ERROR HERE: C\.schar + _ C.ushort = "us" // ERROR HERE: C\.ushort + _ C.uint = "ui" // ERROR HERE: C\.uint + _ C.ulong = "ul" // ERROR HERE: C\.ulong + _ C.longlong = "ll" // ERROR HERE: C\.longlong + _ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong + _ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat + _ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble + ) + + // issue 13830 + // cgo converts C void* to Go unsafe.Pointer, so despite appearances C + // void** is Go *unsafe.Pointer. This test verifies that we detect the + // problem at build time. + { + type v [0]byte + + f := func(p **v) { + C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE + } + var p *v + f(&p) + } + + // issue 16116 + _ = C.fvi(1) // ERROR HERE + + // Issue 16591: Test that we detect an invalid call that was being + // hidden by a type conversion inserted by cgo checking. + { + type x *C.int + var p *x + C.fppi(p) // ERROR HERE + } + + // issue 26745 + _ = func(i int) int { + return C.i + 1 // ERROR HERE: :13 + } + _ = func(i int) { + C.fi(i) // ERROR HERE: :6 + } + + C.fi = C.fi // ERROR HERE + +} diff --git a/libgo/misc/cgo/errors/testdata/err4.go b/libgo/misc/cgo/errors/testdata/err4.go new file mode 100644 index 0000000..8e5f78e --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/err4.go @@ -0,0 +1,15 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +long double x = 0; +*/ +import "C" + +func main() { + _ = C.x // ERROR HERE + _ = C.x +} diff --git a/libgo/misc/cgo/errors/testdata/issue11097a.go b/libgo/misc/cgo/errors/testdata/issue11097a.go new file mode 100644 index 0000000..028d10c --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue11097a.go @@ -0,0 +1,15 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +//enum test { foo, bar }; +*/ +import "C" + +func main() { + var a = C.enum_test(1) // ERROR HERE + _ = a +} diff --git a/libgo/misc/cgo/errors/testdata/issue11097b.go b/libgo/misc/cgo/errors/testdata/issue11097b.go new file mode 100644 index 0000000..b00f24f --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue11097b.go @@ -0,0 +1,15 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +//enum test { foo, bar }; +*/ +import "C" + +func main() { + p := new(C.enum_test) // ERROR HERE + _ = p +} diff --git a/libgo/misc/cgo/errors/testdata/issue14669.go b/libgo/misc/cgo/errors/testdata/issue14669.go new file mode 100644 index 0000000..04d2bcb --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue14669.go @@ -0,0 +1,23 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 14669: test that fails when build with CGO_CFLAGS selecting +// optimization. + +package p + +/* +const int E = 1; + +typedef struct s { + int c; +} s; +*/ +import "C" + +func F() { + _ = C.s{ + c: C.E, + } +} diff --git a/libgo/misc/cgo/errors/testdata/issue18452.go b/libgo/misc/cgo/errors/testdata/issue18452.go new file mode 100644 index 0000000..0386d76 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue18452.go @@ -0,0 +1,18 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 18452: show pos info in undefined name errors + +package p + +import ( + "C" + "fmt" +) + +func a() { + fmt.Println("Hello, world!") + C.function_that_does_not_exist() // ERROR HERE + C.pi // ERROR HERE +} diff --git a/libgo/misc/cgo/errors/testdata/issue18889.go b/libgo/misc/cgo/errors/testdata/issue18889.go new file mode 100644 index 0000000..bba6b8f --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue18889.go @@ -0,0 +1,7 @@ +package main + +import "C" + +func main() { + _ = C.malloc // ERROR HERE +} diff --git a/libgo/misc/cgo/errors/testdata/issue28069.go b/libgo/misc/cgo/errors/testdata/issue28069.go new file mode 100644 index 0000000..e19a3b4 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue28069.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that the error message for an unrepresentable typedef in a +// union appears on the right line. This test is only run if the size +// of long double is larger than 64. + +package main + +/* +typedef long double Float128; + +typedef struct SV { + union { + Float128 float128; + } value; +} SV; +*/ +import "C" + +type ts struct { + tv *C.SV // ERROR HERE +} + +func main() {} diff --git a/libgo/misc/cgo/errors/testdata/issue28721.go b/libgo/misc/cgo/errors/testdata/issue28721.go new file mode 100644 index 0000000..0eb2a92 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/issue28721.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// cgo should reject the use of mangled C names. + +package main + +/* +typedef struct a { + int i; +} a; +void fn(void) {} +*/ +import "C" + +type B _Ctype_struct_a // ERROR HERE + +var a _Ctype_struct_a // ERROR HERE + +type A struct { + a *_Ctype_struct_a // ERROR HERE +} + +var notExist _Ctype_NotExist // ERROR HERE + +func main() { + _Cfunc_fn() // ERROR HERE +} diff --git a/libgo/misc/cgo/errors/testdata/long_double_size.go b/libgo/misc/cgo/errors/testdata/long_double_size.go new file mode 100644 index 0000000..8b797f8 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/long_double_size.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +const int sizeofLongDouble = sizeof(long double); +*/ +import "C" + +import "fmt" + +func main() { + fmt.Println(C.sizeofLongDouble) +} diff --git a/libgo/misc/cgo/errors/testdata/malloc.go b/libgo/misc/cgo/errors/testdata/malloc.go new file mode 100644 index 0000000..65da0208 --- /dev/null +++ b/libgo/misc/cgo/errors/testdata/malloc.go @@ -0,0 +1,34 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that C.malloc does not return nil. + +package main + +// #include +import "C" + +import ( + "fmt" + "runtime" +) + +func main() { + var size C.size_t + size-- + + // The Dragonfly libc succeeds when asked to allocate + // 0xffffffffffffffff bytes, so pass a different value that + // causes it to fail. + if runtime.GOOS == "dragonfly" { + size = C.size_t(0x7fffffff << (32 * (^uintptr(0) >> 63))) + } + + p := C.malloc(size) + if p == nil { + fmt.Println("malloc: C.malloc returned nil") + // Just exit normally--the test script expects this + // program to crash, so exiting normally indicates failure. + } +} diff --git a/libgo/misc/cgo/fortran/test.bash b/libgo/misc/cgo/fortran/test.bash index 1e0d59e..9498da0 100644 --- a/libgo/misc/cgo/fortran/test.bash +++ b/libgo/misc/cgo/fortran/test.bash @@ -14,12 +14,17 @@ goos=$(go env GOOS) libext="so" if [ "$goos" = "darwin" ]; then libext="dylib" +elif [ "$goos" = "aix" ]; then + libtext="a" fi case "$FC" in *gfortran*) libpath=$(dirname $($FC -print-file-name=libgfortran.$libext)) - export CGO_LDFLAGS="$CGO_LDFLAGS -Wl,-rpath,$libpath -L $libpath" + if [ "$goos" != "aix" ]; then + RPATH_FLAG="-Wl,-rpath,$libpath" + fi + export CGO_LDFLAGS="$CGO_LDFLAGS $RPATH_FLAG -L $libpath" ;; esac diff --git a/libgo/misc/cgo/life/c-life.c b/libgo/misc/cgo/life/c-life.c deleted file mode 100644 index f853163..0000000 --- a/libgo/misc/cgo/life/c-life.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include "life.h" -#include "_cgo_export.h" - -const int MYCONST = 0; - -// Do the actual manipulation of the life board in C. This could be -// done easily in Go, we are just using C for demonstration -// purposes. -void -Step(int x, int y, int *a, int *n) -{ - struct GoStart_return r; - - // Use Go to start 4 goroutines each of which handles 1/4 of the - // board. - r = GoStart(0, x, y, 0, x / 2, 0, y / 2, a, n); - assert(r.r0 == 0 && r.r1 == 100); // test multiple returns - r = GoStart(1, x, y, x / 2, x, 0, y / 2, a, n); - assert(r.r0 == 1 && r.r1 == 101); // test multiple returns - GoStart(2, x, y, 0, x / 2, y / 2, y, a, n); - GoStart(3, x, y, x / 2, x, y / 2, y, a, n); - GoWait(0); - GoWait(1); - GoWait(2); - GoWait(3); -} - -// The actual computation. This is called in parallel. -void -DoStep(int xdim, int ydim, int xstart, int xend, int ystart, int yend, int *a, int *n) -{ - int x, y, c, i, j; - - for(x = xstart; x < xend; x++) { - for(y = ystart; y < yend; y++) { - c = 0; - for(i = -1; i <= 1; i++) { - for(j = -1; j <= 1; j++) { - if(x+i >= 0 && x+i < xdim && - y+j >= 0 && y+j < ydim && - (i != 0 || j != 0)) - c += a[(x+i)*xdim + (y+j)] != 0; - } - } - if(c == 3 || (c == 2 && a[x*xdim + y] != 0)) - n[x*xdim + y] = 1; - else - n[x*xdim + y] = 0; - } - } -} diff --git a/libgo/misc/cgo/life/life.go b/libgo/misc/cgo/life/life.go deleted file mode 100644 index 170a620..0000000 --- a/libgo/misc/cgo/life/life.go +++ /dev/null @@ -1,41 +0,0 @@ -// skip - -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package life - -// #include "life.h" -import "C" - -import "unsafe" - -func Run(gen, x, y int, a []int32) { - n := make([]int32, x*y) - for i := 0; i < gen; i++ { - C.Step(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&a[0])), (*C.int)(unsafe.Pointer(&n[0]))) - copy(a, n) - } -} - -// Keep the channels visible from Go. -var chans [4]chan bool - -//export GoStart -// Double return value is just for testing. -func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) { - c := make(chan bool, int(C.MYCONST)) - go func() { - C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n) - c <- true - }() - chans[i] = c - return int(i), int(i + 100) -} - -//export GoWait -func GoWait(i C.int) { - <-chans[i] - chans[i] = nil -} diff --git a/libgo/misc/cgo/life/life.h b/libgo/misc/cgo/life/life.h deleted file mode 100644 index 11d2b97..0000000 --- a/libgo/misc/cgo/life/life.h +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -extern void Step(int, int, int *, int *); -extern void DoStep(int, int, int, int, int, int, int *, int *); -extern const int MYCONST; diff --git a/libgo/misc/cgo/life/life_test.go b/libgo/misc/cgo/life/life_test.go new file mode 100644 index 0000000..3c95d87 --- /dev/null +++ b/libgo/misc/cgo/life/life_test.go @@ -0,0 +1,64 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package life_test + +import ( + "bytes" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestMain(m *testing.M) { + log.SetFlags(log.Lshortfile) + os.Exit(testMain(m)) +} + +func testMain(m *testing.M) int { + GOPATH, err := ioutil.TempDir("", "cgolife") + if err != nil { + log.Panic(err) + } + defer os.RemoveAll(GOPATH) + os.Setenv("GOPATH", GOPATH) + + // Copy testdata into GOPATH/src/cgolife, along with a go.mod file + // declaring the same path. + modRoot := filepath.Join(GOPATH, "src", "cgolife") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := os.Chdir(modRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", modRoot) + if err := ioutil.WriteFile("go.mod", []byte("module cgolife\n"), 0666); err != nil { + log.Panic(err) + } + + return m.Run() +} + +func TestTestRun(t *testing.T) { + if os.Getenv("GOOS") == "android" { + t.Skip("the go tool runs with CGO_ENABLED=0 on the android device") + } + out, err := exec.Command("go", "env", "GOROOT").Output() + if err != nil { + t.Fatal(err) + } + GOROOT := string(bytes.TrimSpace(out)) + + cmd := exec.Command("go", "run", filepath.Join(GOROOT, "test", "run.go"), "-", ".") + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) +} diff --git a/libgo/misc/cgo/life/main.go b/libgo/misc/cgo/life/main.go deleted file mode 100644 index 145a273b..0000000 --- a/libgo/misc/cgo/life/main.go +++ /dev/null @@ -1,49 +0,0 @@ -// run -tags=use_go_run - -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build test_run - -// Run the game of life in C using Go for parallelization. - -package main - -import ( - "flag" - "fmt" - - "." -) - -const MAXDIM = 100 - -var dim = flag.Int("dim", 16, "board dimensions") -var gen = flag.Int("gen", 10, "generations") - -func main() { - flag.Parse() - - var a [MAXDIM * MAXDIM]int32 - for i := 2; i < *dim; i += 8 { - for j := 2; j < *dim-3; j += 8 { - for y := 0; y < 3; y++ { - a[i**dim+j+y] = 1 - } - } - } - - life.Run(*gen, *dim, *dim, a[:]) - - for i := 0; i < *dim; i++ { - for j := 0; j < *dim; j++ { - if a[i**dim+j] == 0 { - fmt.Print(" ") - } else { - fmt.Print("X") - } - } - fmt.Print("\n") - } -} diff --git a/libgo/misc/cgo/life/main.out b/libgo/misc/cgo/life/main.out deleted file mode 100644 index 26fc9c6..0000000 --- a/libgo/misc/cgo/life/main.out +++ /dev/null @@ -1,16 +0,0 @@ - - - XXX XXX - - - - - - - - XXX XXX - - - - - diff --git a/libgo/misc/cgo/life/overlaydir_test.go b/libgo/misc/cgo/life/overlaydir_test.go new file mode 100644 index 0000000..f381ea6 --- /dev/null +++ b/libgo/misc/cgo/life/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package life_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/life/testdata/c-life.c b/libgo/misc/cgo/life/testdata/c-life.c new file mode 100644 index 0000000..f853163 --- /dev/null +++ b/libgo/misc/cgo/life/testdata/c-life.c @@ -0,0 +1,56 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include "life.h" +#include "_cgo_export.h" + +const int MYCONST = 0; + +// Do the actual manipulation of the life board in C. This could be +// done easily in Go, we are just using C for demonstration +// purposes. +void +Step(int x, int y, int *a, int *n) +{ + struct GoStart_return r; + + // Use Go to start 4 goroutines each of which handles 1/4 of the + // board. + r = GoStart(0, x, y, 0, x / 2, 0, y / 2, a, n); + assert(r.r0 == 0 && r.r1 == 100); // test multiple returns + r = GoStart(1, x, y, x / 2, x, 0, y / 2, a, n); + assert(r.r0 == 1 && r.r1 == 101); // test multiple returns + GoStart(2, x, y, 0, x / 2, y / 2, y, a, n); + GoStart(3, x, y, x / 2, x, y / 2, y, a, n); + GoWait(0); + GoWait(1); + GoWait(2); + GoWait(3); +} + +// The actual computation. This is called in parallel. +void +DoStep(int xdim, int ydim, int xstart, int xend, int ystart, int yend, int *a, int *n) +{ + int x, y, c, i, j; + + for(x = xstart; x < xend; x++) { + for(y = ystart; y < yend; y++) { + c = 0; + for(i = -1; i <= 1; i++) { + for(j = -1; j <= 1; j++) { + if(x+i >= 0 && x+i < xdim && + y+j >= 0 && y+j < ydim && + (i != 0 || j != 0)) + c += a[(x+i)*xdim + (y+j)] != 0; + } + } + if(c == 3 || (c == 2 && a[x*xdim + y] != 0)) + n[x*xdim + y] = 1; + else + n[x*xdim + y] = 0; + } + } +} diff --git a/libgo/misc/cgo/life/testdata/life.go b/libgo/misc/cgo/life/testdata/life.go new file mode 100644 index 0000000..2e0af81 --- /dev/null +++ b/libgo/misc/cgo/life/testdata/life.go @@ -0,0 +1,41 @@ +// skip + +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgolife + +// #include "life.h" +import "C" + +import "unsafe" + +func Run(gen, x, y int, a []int32) { + n := make([]int32, x*y) + for i := 0; i < gen; i++ { + C.Step(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&a[0])), (*C.int)(unsafe.Pointer(&n[0]))) + copy(a, n) + } +} + +// Keep the channels visible from Go. +var chans [4]chan bool + +//export GoStart +// Double return value is just for testing. +func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) { + c := make(chan bool, int(C.MYCONST)) + go func() { + C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n) + c <- true + }() + chans[i] = c + return int(i), int(i + 100) +} + +//export GoWait +func GoWait(i C.int) { + <-chans[i] + chans[i] = nil +} diff --git a/libgo/misc/cgo/life/testdata/life.h b/libgo/misc/cgo/life/testdata/life.h new file mode 100644 index 0000000..11d2b97 --- /dev/null +++ b/libgo/misc/cgo/life/testdata/life.h @@ -0,0 +1,7 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +extern void Step(int, int, int *, int *); +extern void DoStep(int, int, int, int, int, int, int *, int *); +extern const int MYCONST; diff --git a/libgo/misc/cgo/life/testdata/main.go b/libgo/misc/cgo/life/testdata/main.go new file mode 100644 index 0000000..cc2ca7c --- /dev/null +++ b/libgo/misc/cgo/life/testdata/main.go @@ -0,0 +1,49 @@ +// run -tags=use_go_run + +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build test_run + +// Run the game of life in C using Go for parallelization. + +package main + +import ( + "flag" + "fmt" + + "cgolife" +) + +const MAXDIM = 100 + +var dim = flag.Int("dim", 16, "board dimensions") +var gen = flag.Int("gen", 10, "generations") + +func main() { + flag.Parse() + + var a [MAXDIM * MAXDIM]int32 + for i := 2; i < *dim; i += 8 { + for j := 2; j < *dim-3; j += 8 { + for y := 0; y < 3; y++ { + a[i**dim+j+y] = 1 + } + } + } + + cgolife.Run(*gen, *dim, *dim, a[:]) + + for i := 0; i < *dim; i++ { + for j := 0; j < *dim; j++ { + if a[i**dim+j] == 0 { + fmt.Print(" ") + } else { + fmt.Print("X") + } + } + fmt.Print("\n") + } +} diff --git a/libgo/misc/cgo/life/testdata/main.out b/libgo/misc/cgo/life/testdata/main.out new file mode 100644 index 0000000..26fc9c6 --- /dev/null +++ b/libgo/misc/cgo/life/testdata/main.out @@ -0,0 +1,16 @@ + + + XXX XXX + + + + + + + + XXX XXX + + + + + diff --git a/libgo/misc/cgo/stdio/chain.go b/libgo/misc/cgo/stdio/chain.go deleted file mode 100644 index cdc3852..0000000 --- a/libgo/misc/cgo/stdio/chain.go +++ /dev/null @@ -1,48 +0,0 @@ -// run -tags=use_go_run - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build test_run - -// Pass numbers along a chain of threads. - -package main - -import ( - "runtime" - "strconv" - - "../stdio" -) - -const N = 10 -const R = 5 - -func link(left chan<- int, right <-chan int) { - // Keep the links in dedicated operating system - // threads, so that this program tests coordination - // between pthreads and not just goroutines. - runtime.LockOSThread() - for { - v := <-right - stdio.Stdout.WriteString(strconv.Itoa(v) + "\n") - left <- 1 + v - } -} - -func main() { - leftmost := make(chan int) - var left chan int - right := leftmost - for i := 0; i < N; i++ { - left, right = right, make(chan int) - go link(left, right) - } - for i := 0; i < R; i++ { - right <- 0 - x := <-leftmost - stdio.Stdout.WriteString(strconv.Itoa(x) + "\n") - } -} diff --git a/libgo/misc/cgo/stdio/chain.out b/libgo/misc/cgo/stdio/chain.out deleted file mode 100644 index 963cf9b..0000000 --- a/libgo/misc/cgo/stdio/chain.out +++ /dev/null @@ -1,55 +0,0 @@ -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 diff --git a/libgo/misc/cgo/stdio/fib.go b/libgo/misc/cgo/stdio/fib.go deleted file mode 100644 index 58f185c..0000000 --- a/libgo/misc/cgo/stdio/fib.go +++ /dev/null @@ -1,52 +0,0 @@ -// run -tags=use_go_run - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build test_run - -// Compute Fibonacci numbers with two goroutines -// that pass integers back and forth. No actual -// concurrency, just threads and synchronization -// and foreign code on multiple pthreads. - -package main - -import ( - "runtime" - "strconv" - - "../stdio" -) - -func fibber(c, out chan int64, i int64) { - // Keep the fibbers in dedicated operating system - // threads, so that this program tests coordination - // between pthreads and not just goroutines. - runtime.LockOSThread() - - if i == 0 { - c <- i - } - for { - j := <-c - stdio.Stdout.WriteString(strconv.FormatInt(j, 10) + "\n") - out <- j - <-out - i += j - c <- i - } -} - -func main() { - c := make(chan int64) - out := make(chan int64) - go fibber(c, out, 0) - go fibber(c, out, 1) - <-out - for i := 0; i < 90; i++ { - out <- 1 - <-out - } -} diff --git a/libgo/misc/cgo/stdio/fib.out b/libgo/misc/cgo/stdio/fib.out deleted file mode 100644 index 17ff503..0000000 --- a/libgo/misc/cgo/stdio/fib.out +++ /dev/null @@ -1,91 +0,0 @@ -0 -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 -610 -987 -1597 -2584 -4181 -6765 -10946 -17711 -28657 -46368 -75025 -121393 -196418 -317811 -514229 -832040 -1346269 -2178309 -3524578 -5702887 -9227465 -14930352 -24157817 -39088169 -63245986 -102334155 -165580141 -267914296 -433494437 -701408733 -1134903170 -1836311903 -2971215073 -4807526976 -7778742049 -12586269025 -20365011074 -32951280099 -53316291173 -86267571272 -139583862445 -225851433717 -365435296162 -591286729879 -956722026041 -1548008755920 -2504730781961 -4052739537881 -6557470319842 -10610209857723 -17167680177565 -27777890035288 -44945570212853 -72723460248141 -117669030460994 -190392490709135 -308061521170129 -498454011879264 -806515533049393 -1304969544928657 -2111485077978050 -3416454622906707 -5527939700884757 -8944394323791464 -14472334024676221 -23416728348467685 -37889062373143906 -61305790721611591 -99194853094755497 -160500643816367088 -259695496911122585 -420196140727489673 -679891637638612258 -1100087778366101931 -1779979416004714189 -2880067194370816120 diff --git a/libgo/misc/cgo/stdio/file.go b/libgo/misc/cgo/stdio/file.go deleted file mode 100644 index a024f2c..0000000 --- a/libgo/misc/cgo/stdio/file.go +++ /dev/null @@ -1,44 +0,0 @@ -// skip - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -A trivial example of wrapping a C library in Go. -For a more complex example and explanation, -see ../gmp/gmp.go. -*/ - -package stdio - -/* -#include -#include -#include -#include - -char* greeting = "hello, world"; -*/ -import "C" -import "unsafe" - -type File C.FILE - -// Test reference to library symbol. -// Stdout and stderr are too special to be a reliable test. -//var = C.environ - -func (f *File) WriteString(s string) { - p := C.CString(s) - C.fputs(p, (*C.FILE)(f)) - C.free(unsafe.Pointer(p)) - f.Flush() -} - -func (f *File) Flush() { - C.fflush((*C.FILE)(f)) -} - -var Greeting = C.GoString(C.greeting) -var Gbytes = C.GoBytes(unsafe.Pointer(C.greeting), C.int(len(Greeting))) diff --git a/libgo/misc/cgo/stdio/hello.go b/libgo/misc/cgo/stdio/hello.go deleted file mode 100644 index 56220d3..0000000 --- a/libgo/misc/cgo/stdio/hello.go +++ /dev/null @@ -1,15 +0,0 @@ -// run -tags=use_go_run - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build test_run - -package main - -import "../stdio" - -func main() { - stdio.Stdout.WriteString(stdio.Greeting + "\n") -} diff --git a/libgo/misc/cgo/stdio/hello.out b/libgo/misc/cgo/stdio/hello.out deleted file mode 100644 index 4b5fa63..0000000 --- a/libgo/misc/cgo/stdio/hello.out +++ /dev/null @@ -1 +0,0 @@ -hello, world diff --git a/libgo/misc/cgo/stdio/overlaydir_test.go b/libgo/misc/cgo/stdio/overlaydir_test.go new file mode 100644 index 0000000..8a8dcdb --- /dev/null +++ b/libgo/misc/cgo/stdio/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stdio_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/stdio/run.out b/libgo/misc/cgo/stdio/run.out deleted file mode 100644 index c0e4965..0000000 --- a/libgo/misc/cgo/stdio/run.out +++ /dev/null @@ -1,150 +0,0 @@ -* hello -hello, world -* fib -0 -1 -1 -2 -3 -5 -8 -13 -21 -34 -55 -89 -144 -233 -377 -610 -987 -1597 -2584 -4181 -6765 -10946 -17711 -28657 -46368 -75025 -121393 -196418 -317811 -514229 -832040 -1346269 -2178309 -3524578 -5702887 -9227465 -14930352 -24157817 -39088169 -63245986 -102334155 -165580141 -267914296 -433494437 -701408733 -1134903170 -1836311903 -2971215073 -4807526976 -7778742049 -12586269025 -20365011074 -32951280099 -53316291173 -86267571272 -139583862445 -225851433717 -365435296162 -591286729879 -956722026041 -1548008755920 -2504730781961 -4052739537881 -6557470319842 -10610209857723 -17167680177565 -27777890035288 -44945570212853 -72723460248141 -117669030460994 -190392490709135 -308061521170129 -498454011879264 -806515533049393 -1304969544928657 -2111485077978050 -3416454622906707 -5527939700884757 -8944394323791464 -14472334024676221 -23416728348467685 -37889062373143906 -61305790721611591 -99194853094755497 -160500643816367088 -259695496911122585 -420196140727489673 -679891637638612258 -1100087778366101931 -1779979416004714189 -2880067194370816120 -* chain -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 diff --git a/libgo/misc/cgo/stdio/stdio.go b/libgo/misc/cgo/stdio/stdio.go deleted file mode 100644 index d216e44..0000000 --- a/libgo/misc/cgo/stdio/stdio.go +++ /dev/null @@ -1,22 +0,0 @@ -// skip - -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package stdio - -/* -#include - -// on mingw, stderr and stdout are defined as &_iob[FILENO] -// on netbsd, they are defined as &__sF[FILENO] -// and cgo doesn't recognize them, so write a function to get them, -// instead of depending on internals of libc implementation. -FILE *getStdout(void) { return stdout; } -FILE *getStderr(void) { return stderr; } -*/ -import "C" - -var Stdout = (*File)(C.getStdout()) -var Stderr = (*File)(C.getStderr()) diff --git a/libgo/misc/cgo/stdio/stdio_test.go b/libgo/misc/cgo/stdio/stdio_test.go new file mode 100644 index 0000000..ab5d328 --- /dev/null +++ b/libgo/misc/cgo/stdio/stdio_test.go @@ -0,0 +1,64 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stdio_test + +import ( + "bytes" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestMain(m *testing.M) { + log.SetFlags(log.Lshortfile) + os.Exit(testMain(m)) +} + +func testMain(m *testing.M) int { + GOPATH, err := ioutil.TempDir("", "cgostdio") + if err != nil { + log.Panic(err) + } + defer os.RemoveAll(GOPATH) + os.Setenv("GOPATH", GOPATH) + + // Copy testdata into GOPATH/src/cgostdio, along with a go.mod file + // declaring the same path. + modRoot := filepath.Join(GOPATH, "src", "cgostdio") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := os.Chdir(modRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", modRoot) + if err := ioutil.WriteFile("go.mod", []byte("module cgostdio\n"), 0666); err != nil { + log.Panic(err) + } + + return m.Run() +} + +func TestTestRun(t *testing.T) { + if os.Getenv("GOOS") == "android" { + t.Skip("subpackage stdio is not available on android") + } + out, err := exec.Command("go", "env", "GOROOT").Output() + if err != nil { + t.Fatal(err) + } + GOROOT := string(bytes.TrimSpace(out)) + + cmd := exec.Command("go", "run", filepath.Join(GOROOT, "test", "run.go"), "-", ".") + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) +} diff --git a/libgo/misc/cgo/stdio/testdata/chain.go b/libgo/misc/cgo/stdio/testdata/chain.go new file mode 100644 index 0000000..6c3f406 --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/chain.go @@ -0,0 +1,48 @@ +// run -tags=use_go_run + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build test_run + +// Pass numbers along a chain of threads. + +package main + +import ( + "runtime" + "strconv" + + "cgostdio/stdio" +) + +const N = 10 +const R = 5 + +func link(left chan<- int, right <-chan int) { + // Keep the links in dedicated operating system + // threads, so that this program tests coordination + // between pthreads and not just goroutines. + runtime.LockOSThread() + for { + v := <-right + stdio.Stdout.WriteString(strconv.Itoa(v) + "\n") + left <- 1 + v + } +} + +func main() { + leftmost := make(chan int) + var left chan int + right := leftmost + for i := 0; i < N; i++ { + left, right = right, make(chan int) + go link(left, right) + } + for i := 0; i < R; i++ { + right <- 0 + x := <-leftmost + stdio.Stdout.WriteString(strconv.Itoa(x) + "\n") + } +} diff --git a/libgo/misc/cgo/stdio/testdata/chain.out b/libgo/misc/cgo/stdio/testdata/chain.out new file mode 100644 index 0000000..963cf9b --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/chain.out @@ -0,0 +1,55 @@ +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/libgo/misc/cgo/stdio/testdata/fib.go b/libgo/misc/cgo/stdio/testdata/fib.go new file mode 100644 index 0000000..49cb0ea --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/fib.go @@ -0,0 +1,52 @@ +// run -tags=use_go_run + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build test_run + +// Compute Fibonacci numbers with two goroutines +// that pass integers back and forth. No actual +// concurrency, just threads and synchronization +// and foreign code on multiple pthreads. + +package main + +import ( + "runtime" + "strconv" + + "cgostdio/stdio" +) + +func fibber(c, out chan int64, i int64) { + // Keep the fibbers in dedicated operating system + // threads, so that this program tests coordination + // between pthreads and not just goroutines. + runtime.LockOSThread() + + if i == 0 { + c <- i + } + for { + j := <-c + stdio.Stdout.WriteString(strconv.FormatInt(j, 10) + "\n") + out <- j + <-out + i += j + c <- i + } +} + +func main() { + c := make(chan int64) + out := make(chan int64) + go fibber(c, out, 0) + go fibber(c, out, 1) + <-out + for i := 0; i < 90; i++ { + out <- 1 + <-out + } +} diff --git a/libgo/misc/cgo/stdio/testdata/fib.out b/libgo/misc/cgo/stdio/testdata/fib.out new file mode 100644 index 0000000..17ff503 --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/fib.out @@ -0,0 +1,91 @@ +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 +6765 +10946 +17711 +28657 +46368 +75025 +121393 +196418 +317811 +514229 +832040 +1346269 +2178309 +3524578 +5702887 +9227465 +14930352 +24157817 +39088169 +63245986 +102334155 +165580141 +267914296 +433494437 +701408733 +1134903170 +1836311903 +2971215073 +4807526976 +7778742049 +12586269025 +20365011074 +32951280099 +53316291173 +86267571272 +139583862445 +225851433717 +365435296162 +591286729879 +956722026041 +1548008755920 +2504730781961 +4052739537881 +6557470319842 +10610209857723 +17167680177565 +27777890035288 +44945570212853 +72723460248141 +117669030460994 +190392490709135 +308061521170129 +498454011879264 +806515533049393 +1304969544928657 +2111485077978050 +3416454622906707 +5527939700884757 +8944394323791464 +14472334024676221 +23416728348467685 +37889062373143906 +61305790721611591 +99194853094755497 +160500643816367088 +259695496911122585 +420196140727489673 +679891637638612258 +1100087778366101931 +1779979416004714189 +2880067194370816120 diff --git a/libgo/misc/cgo/stdio/testdata/hello.go b/libgo/misc/cgo/stdio/testdata/hello.go new file mode 100644 index 0000000..046bfee --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/hello.go @@ -0,0 +1,15 @@ +// run -tags=use_go_run + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build test_run + +package main + +import "cgostdio/stdio" + +func main() { + stdio.Stdout.WriteString(stdio.Greeting + "\n") +} diff --git a/libgo/misc/cgo/stdio/testdata/hello.out b/libgo/misc/cgo/stdio/testdata/hello.out new file mode 100644 index 0000000..4b5fa63 --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/hello.out @@ -0,0 +1 @@ +hello, world diff --git a/libgo/misc/cgo/stdio/testdata/run.out b/libgo/misc/cgo/stdio/testdata/run.out new file mode 100644 index 0000000..c0e4965 --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/run.out @@ -0,0 +1,150 @@ +* hello +hello, world +* fib +0 +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 +6765 +10946 +17711 +28657 +46368 +75025 +121393 +196418 +317811 +514229 +832040 +1346269 +2178309 +3524578 +5702887 +9227465 +14930352 +24157817 +39088169 +63245986 +102334155 +165580141 +267914296 +433494437 +701408733 +1134903170 +1836311903 +2971215073 +4807526976 +7778742049 +12586269025 +20365011074 +32951280099 +53316291173 +86267571272 +139583862445 +225851433717 +365435296162 +591286729879 +956722026041 +1548008755920 +2504730781961 +4052739537881 +6557470319842 +10610209857723 +17167680177565 +27777890035288 +44945570212853 +72723460248141 +117669030460994 +190392490709135 +308061521170129 +498454011879264 +806515533049393 +1304969544928657 +2111485077978050 +3416454622906707 +5527939700884757 +8944394323791464 +14472334024676221 +23416728348467685 +37889062373143906 +61305790721611591 +99194853094755497 +160500643816367088 +259695496911122585 +420196140727489673 +679891637638612258 +1100087778366101931 +1779979416004714189 +2880067194370816120 +* chain +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/libgo/misc/cgo/stdio/testdata/stdio/file.go b/libgo/misc/cgo/stdio/testdata/stdio/file.go new file mode 100644 index 0000000..a024f2c --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/stdio/file.go @@ -0,0 +1,44 @@ +// skip + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +A trivial example of wrapping a C library in Go. +For a more complex example and explanation, +see ../gmp/gmp.go. +*/ + +package stdio + +/* +#include +#include +#include +#include + +char* greeting = "hello, world"; +*/ +import "C" +import "unsafe" + +type File C.FILE + +// Test reference to library symbol. +// Stdout and stderr are too special to be a reliable test. +//var = C.environ + +func (f *File) WriteString(s string) { + p := C.CString(s) + C.fputs(p, (*C.FILE)(f)) + C.free(unsafe.Pointer(p)) + f.Flush() +} + +func (f *File) Flush() { + C.fflush((*C.FILE)(f)) +} + +var Greeting = C.GoString(C.greeting) +var Gbytes = C.GoBytes(unsafe.Pointer(C.greeting), C.int(len(Greeting))) diff --git a/libgo/misc/cgo/stdio/testdata/stdio/stdio.go b/libgo/misc/cgo/stdio/testdata/stdio/stdio.go new file mode 100644 index 0000000..d216e44 --- /dev/null +++ b/libgo/misc/cgo/stdio/testdata/stdio/stdio.go @@ -0,0 +1,22 @@ +// skip + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stdio + +/* +#include + +// on mingw, stderr and stdout are defined as &_iob[FILENO] +// on netbsd, they are defined as &__sF[FILENO] +// and cgo doesn't recognize them, so write a function to get them, +// instead of depending on internals of libc implementation. +FILE *getStdout(void) { return stdout; } +FILE *getStderr(void) { return stderr; } +*/ +import "C" + +var Stdout = (*File)(C.getStdout()) +var Stderr = (*File)(C.getStderr()) diff --git a/libgo/misc/cgo/test/align.go b/libgo/misc/cgo/test/align.go deleted file mode 100644 index a23b44f..0000000 --- a/libgo/misc/cgo/test/align.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include - -typedef unsigned char Uint8; -typedef unsigned short Uint16; - -typedef enum { - MOD1 = 0x0000, - MODX = 0x8000 -} SDLMod; - -typedef enum { - A = 1, - B = 322, - SDLK_LAST -} SDLKey; - -typedef struct SDL_keysym { - Uint8 scancode; - SDLKey sym; - SDLMod mod; - Uint16 unicode; -} SDL_keysym; - -typedef struct SDL_KeyboardEvent { - Uint8 typ; - Uint8 which; - Uint8 state; - SDL_keysym keysym; -} SDL_KeyboardEvent; - -void makeEvent(SDL_KeyboardEvent *event) { - unsigned char *p; - int i; - - p = (unsigned char*)event; - for (i=0; ityp == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni; -} - -void cTest(SDL_KeyboardEvent *event) { - printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, - event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); - fflush(stdout); -} - -*/ -import "C" - -import ( - "testing" -) - -func testAlign(t *testing.T) { - var evt C.SDL_KeyboardEvent - C.makeEvent(&evt) - if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { - t.Error("*** bad alignment") - C.cTest(&evt) - t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", - evt.typ, evt.which, evt.state, evt.keysym.scancode, - evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) - t.Error(evt) - } -} diff --git a/libgo/misc/cgo/test/api.go b/libgo/misc/cgo/test/api.go deleted file mode 100644 index d2b09cb..0000000 --- a/libgo/misc/cgo/test/api.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// API Compatibility Checks for cgo - -package cgotest - -// #include -// -// // Test for issue 17723. -// typedef char *cstring_pointer; -// static void cstring_pointer_fun(cstring_pointer dummy) { } -// -// const char *api_hello = "hello!"; -import "C" -import "unsafe" - -func testAPI() { - var cs *C.char - cs = C.CString("hello") - defer C.free(unsafe.Pointer(cs)) - var s string - s = C.GoString((*C.char)(C.api_hello)) - s = C.GoStringN((*C.char)(C.api_hello), C.int(6)) - var b []byte - b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6)) - _, _ = s, b - C.cstring_pointer_fun(nil) -} diff --git a/libgo/misc/cgo/test/basic.go b/libgo/misc/cgo/test/basic.go deleted file mode 100644 index 2655a66..0000000 --- a/libgo/misc/cgo/test/basic.go +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Basic test cases for cgo. - -package cgotest - -/* -#include -#include -#include -#include - -#define SHIFT(x, y) ((x)<<(y)) -#define KILO SHIFT(1, 10) -#define UINT32VAL 0xc008427bU - -enum E { - Enum1 = 1, - Enum2 = 2, -}; - -typedef unsigned char cgo_uuid_t[20]; - -void uuid_generate(cgo_uuid_t x) { - x[0] = 0; -} - -struct S { - int x; -}; - -const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - -extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); - -enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } - -// issue 1222 -typedef union { - long align; -} xxpthread_mutex_t; - -struct ibv_async_event { - union { - int x; - } element; -}; - -struct ibv_context { - xxpthread_mutex_t mutex; -}; - -int add(int x, int y) { - return x+y; -}; -*/ -import "C" -import ( - "runtime" - "syscall" - "testing" - "unsafe" -) - -const EINVAL = C.EINVAL /* test #define */ - -var KILO = C.KILO - -func uuidgen() { - var uuid C.cgo_uuid_t - C.uuid_generate(&uuid[0]) -} - -func Strtol(s string, base int) (int, error) { - p := C.CString(s) - n, err := C.strtol(p, nil, C.int(base)) - C.free(unsafe.Pointer(p)) - return int(n), err -} - -func Atol(s string) int { - p := C.CString(s) - n := C.atol(p) - C.free(unsafe.Pointer(p)) - return int(n) -} - -func testConst(t *testing.T) { - C.myConstFunc(nil, 0, nil) -} - -func testEnum(t *testing.T) { - if C.Enum1 != 1 || C.Enum2 != 2 { - t.Error("bad enum", C.Enum1, C.Enum2) - } -} - -func testAtol(t *testing.T) { - l := Atol("123") - if l != 123 { - t.Error("Atol 123: ", l) - } -} - -func testErrno(t *testing.T) { - p := C.CString("no-such-file") - m := C.CString("r") - f, err := C.fopen(p, m) - C.free(unsafe.Pointer(p)) - C.free(unsafe.Pointer(m)) - if err == nil { - C.fclose(f) - t.Fatalf("C.fopen: should fail") - } - if err != syscall.ENOENT { - t.Fatalf("C.fopen: unexpected error: %v", err) - } -} - -func testMultipleAssign(t *testing.T) { - p := C.CString("234") - n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) - if runtime.GOOS == "openbsd" { - // Bug in OpenBSD strtol(3) - base > 36 succeeds. - if (n != 0 && n != 239089) || m != 234 { - t.Fatal("Strtol x2: ", n, m) - } - } else if n != 0 || m != 234 { - t.Fatal("Strtol x2: ", n, m) - } - C.free(unsafe.Pointer(p)) -} - -var ( - cuint = (C.uint)(0) - culong C.ulong - cchar C.char -) - -type Context struct { - ctx *C.struct_ibv_context -} - -func benchCgoCall(b *testing.B) { - const x = C.int(2) - const y = C.int(3) - for i := 0; i < b.N; i++ { - C.add(x, y) - } -} - -var sinkString string - -func benchGoString(b *testing.B) { - for i := 0; i < b.N; i++ { - sinkString = C.GoString(C.cstr) - } - const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890" - if sinkString != want { - b.Fatalf("%q != %q", sinkString, want) - } -} - -// Issue 2470. -func testUnsignedInt(t *testing.T) { - a := (int64)(C.UINT32VAL) - b := (int64)(0xc008427b) - if a != b { - t.Errorf("Incorrect unsigned int - got %x, want %x", a, b) - } -} - -// Static (build-time) test that syntax traversal visits all operands of s[i:j:k]. -func sliceOperands(array [2000]int) { - _ = array[C.KILO:C.KILO:C.KILO] // no type error -} - -// set in cgo_thread_lock.go init -var testThreadLockFunc = func(*testing.T) {} diff --git a/libgo/misc/cgo/test/callback.go b/libgo/misc/cgo/test/callback.go index 4fc6b39..e749650 100644 --- a/libgo/misc/cgo/test/callback.go +++ b/libgo/misc/cgo/test/callback.go @@ -199,7 +199,7 @@ func testCallbackCallers(t *testing.T) { t.Errorf("expected %d frames, got %d", len(name), n) } for i := 0; i < n; i++ { - f := runtime.FuncForPC(pc[i]) + f := runtime.FuncForPC(pc[i] - 1) // TODO: use runtime.CallersFrames if f == nil { t.Fatalf("expected non-nil Func for pc %d", pc[i]) } @@ -209,6 +209,10 @@ func testCallbackCallers(t *testing.T) { if strings.HasPrefix(fname, "_") { fname = path.Base(f.Name()[1:]) } + // In module mode, this package has a fully-qualified import path. + // Remove it if present. + fname = strings.TrimPrefix(fname, "misc/cgo/") + namei := "" if i < len(name) { namei = name[i] diff --git a/libgo/misc/cgo/test/cflags.go b/libgo/misc/cgo/test/cflags.go deleted file mode 100644 index bc290bf..0000000 --- a/libgo/misc/cgo/test/cflags.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that the #cgo CFLAGS directive works, -// with and without platform filters. -// See https://golang.org/issue/5224 for details. -package cgotest - -/* -#cgo CFLAGS: -DCOMMON_VALUE=123 -#cgo windows CFLAGS: -DIS_WINDOWS=1 -#cgo !windows CFLAGS: -DIS_WINDOWS=0 -int common = COMMON_VALUE; -int is_windows = IS_WINDOWS; -*/ -import "C" - -import ( - "runtime" - "testing" -) - -func testCflags(t *testing.T) { - is_windows := C.is_windows == 1 - if is_windows != (runtime.GOOS == "windows") { - t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) - } - if C.common != 123 { - t.Errorf("common: %v (expected 123)", C.common) - } -} diff --git a/libgo/misc/cgo/test/cgo_linux_test.go b/libgo/misc/cgo/test/cgo_linux_test.go index 9c15f69..7b56e11 100644 --- a/libgo/misc/cgo/test/cgo_linux_test.go +++ b/libgo/misc/cgo/test/cgo_linux_test.go @@ -4,9 +4,16 @@ package cgotest -import "testing" +import ( + "runtime" + "testing" +) -func TestSetgid(t *testing.T) { testSetgid(t) } +func TestSetgid(t *testing.T) { + if runtime.GOOS == "android" { + t.Skip("unsupported on Android") + } + testSetgid(t) +} func Test6997(t *testing.T) { test6997(t) } func TestBuildID(t *testing.T) { testBuildID(t) } -func Test9400(t *testing.T) { test9400(t) } diff --git a/libgo/misc/cgo/test/cgo_stubs_android_test.go b/libgo/misc/cgo/test/cgo_stubs_android_test.go index 710e094..a1c2482 100644 --- a/libgo/misc/cgo/test/cgo_stubs_android_test.go +++ b/libgo/misc/cgo/test/cgo_stubs_android_test.go @@ -8,6 +8,5 @@ import "testing" // Stubs for tests that fails to build on Android func test6997(t *testing.T) {} -func test3775(t *testing.T) {} func test8694(t *testing.T) {} func testSigaltstack(t *testing.T) {} diff --git a/libgo/misc/cgo/test/cgo_test.go b/libgo/misc/cgo/test/cgo_test.go index 2cb93d9..c66df2c 100644 --- a/libgo/misc/cgo/test/cgo_test.go +++ b/libgo/misc/cgo/test/cgo_test.go @@ -10,91 +10,86 @@ import "testing" // so that they can use cgo (import "C"). // These wrappers are here for gotest to find. -func TestAlign(t *testing.T) { testAlign(t) } -func TestConst(t *testing.T) { testConst(t) } -func TestEnum(t *testing.T) { testEnum(t) } -func TestAtol(t *testing.T) { testAtol(t) } -func TestErrno(t *testing.T) { testErrno(t) } -func TestMultipleAssign(t *testing.T) { testMultipleAssign(t) } -func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) } -func TestCallback(t *testing.T) { testCallback(t) } -func TestCallbackGC(t *testing.T) { testCallbackGC(t) } -func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) } -func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) } -func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) } -func TestPanicFromC(t *testing.T) { testPanicFromC(t) } -func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) } -func TestBlocking(t *testing.T) { testBlocking(t) } func Test1328(t *testing.T) { test1328(t) } -func TestParallelSleep(t *testing.T) { testParallelSleep(t) } -func TestSetEnv(t *testing.T) { testSetEnv(t) } -func TestHelpers(t *testing.T) { testHelpers(t) } -func TestLibgcc(t *testing.T) { testLibgcc(t) } func Test1635(t *testing.T) { test1635(t) } -func TestPrintf(t *testing.T) { testPrintf(t) } -func Test4029(t *testing.T) { test4029(t) } -func TestBoolAlign(t *testing.T) { testBoolAlign(t) } +func Test3250(t *testing.T) { test3250(t) } func Test3729(t *testing.T) { test3729(t) } func Test3775(t *testing.T) { test3775(t) } -func TestCthread(t *testing.T) { testCthread(t) } -func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) } +func Test4029(t *testing.T) { test4029(t) } +func Test4339(t *testing.T) { test4339(t) } func Test5227(t *testing.T) { test5227(t) } -func TestCflags(t *testing.T) { testCflags(t) } +func Test5242(t *testing.T) { test5242(t) } func Test5337(t *testing.T) { test5337(t) } func Test5548(t *testing.T) { test5548(t) } func Test5603(t *testing.T) { test5603(t) } -func Test6833(t *testing.T) { test6833(t) } -func Test3250(t *testing.T) { test3250(t) } -func TestCallbackStack(t *testing.T) { testCallbackStack(t) } -func TestFpVar(t *testing.T) { testFpVar(t) } -func Test4339(t *testing.T) { test4339(t) } -func Test6390(t *testing.T) { test6390(t) } func Test5986(t *testing.T) { test5986(t) } -func Test7665(t *testing.T) { test7665(t) } -func TestNaming(t *testing.T) { testNaming(t) } +func Test6390(t *testing.T) { test6390(t) } +func Test6833(t *testing.T) { test6833(t) } +func Test6907(t *testing.T) { test6907(t) } +func Test6907Go(t *testing.T) { test6907Go(t) } func Test7560(t *testing.T) { test7560(t) } -func Test5242(t *testing.T) { test5242(t) } -func Test8092(t *testing.T) { test8092(t) } +func Test7665(t *testing.T) { test7665(t) } func Test7978(t *testing.T) { test7978(t) } -func Test8694(t *testing.T) { test8694(t) } +func Test8092(t *testing.T) { test8092(t) } func Test8517(t *testing.T) { test8517(t) } +func Test8694(t *testing.T) { test8694(t) } func Test8811(t *testing.T) { test8811(t) } -func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) } -func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) } -func Test9026(t *testing.T) { test9026(t) } -func Test9510(t *testing.T) { test9510(t) } func Test9557(t *testing.T) { test9557(t) } func Test10303(t *testing.T) { test10303(t, 10) } func Test11925(t *testing.T) { test11925(t) } func Test12030(t *testing.T) { test12030(t) } -func TestGCC68255(t *testing.T) { testGCC68255(t) } -func TestCallGoWithString(t *testing.T) { testCallGoWithString(t) } func Test14838(t *testing.T) { test14838(t) } -func Test8756(t *testing.T) { test8756(t) } func Test17065(t *testing.T) { test17065(t) } -func TestThreadLock(t *testing.T) { testThreadLockFunc(t) } -func TestCheckConst(t *testing.T) { testCheckConst(t) } func Test17537(t *testing.T) { test17537(t) } func Test18126(t *testing.T) { test18126(t) } -func Test20369(t *testing.T) { test20369(t) } func Test18720(t *testing.T) { test18720(t) } -func Test20266(t *testing.T) { test20266(t) } func Test20129(t *testing.T) { test20129(t) } +func Test20369(t *testing.T) { test20369(t) } func Test20910(t *testing.T) { test20910(t) } func Test21708(t *testing.T) { test21708(t) } func Test21809(t *testing.T) { test21809(t) } -func Test6907(t *testing.T) { test6907(t) } -func Test6907Go(t *testing.T) { test6907Go(t) } func Test21897(t *testing.T) { test21897(t) } func Test22906(t *testing.T) { test22906(t) } +func Test23356(t *testing.T) { test23356(t) } func Test24206(t *testing.T) { test24206(t) } func Test25143(t *testing.T) { test25143(t) } -func Test23356(t *testing.T) { test23356(t) } func Test26066(t *testing.T) { test26066(t) } -func Test26213(t *testing.T) { test26213(t) } func Test27660(t *testing.T) { test27660(t) } func Test28896(t *testing.T) { test28896(t) } func Test30065(t *testing.T) { test30065(t) } +func Test32579(t *testing.T) { test32579(t) } +func TestAlign(t *testing.T) { testAlign(t) } +func TestAtol(t *testing.T) { testAtol(t) } +func TestBlocking(t *testing.T) { testBlocking(t) } +func TestBoolAlign(t *testing.T) { testBoolAlign(t) } +func TestCallGoWithString(t *testing.T) { testCallGoWithString(t) } +func TestCallback(t *testing.T) { testCallback(t) } +func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) } +func TestCallbackGC(t *testing.T) { testCallbackGC(t) } +func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) } +func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) } +func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) } +func TestCallbackStack(t *testing.T) { testCallbackStack(t) } +func TestCflags(t *testing.T) { testCflags(t) } +func TestCheckConst(t *testing.T) { testCheckConst(t) } +func TestConst(t *testing.T) { testConst(t) } +func TestCthread(t *testing.T) { testCthread(t) } +func TestEnum(t *testing.T) { testEnum(t) } +func TestErrno(t *testing.T) { testErrno(t) } +func TestFpVar(t *testing.T) { testFpVar(t) } +func TestHelpers(t *testing.T) { testHelpers(t) } +func TestLibgcc(t *testing.T) { testLibgcc(t) } +func TestMultipleAssign(t *testing.T) { testMultipleAssign(t) } +func TestNaming(t *testing.T) { testNaming(t) } +func TestPanicFromC(t *testing.T) { testPanicFromC(t) } +func TestParallelSleep(t *testing.T) { testParallelSleep(t) } +func TestPrintf(t *testing.T) { testPrintf(t) } +func TestReturnAfterGrow(t *testing.T) { testReturnAfterGrow(t) } +func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) } +func TestSetEnv(t *testing.T) { testSetEnv(t) } +func TestThreadLock(t *testing.T) { testThreadLockFunc(t) } +func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) } +func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } func BenchmarkGoString(b *testing.B) { benchGoString(b) } diff --git a/libgo/misc/cgo/test/checkconst.go b/libgo/misc/cgo/test/checkconst.go deleted file mode 100644 index 0160c1e..0000000 --- a/libgo/misc/cgo/test/checkconst.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test a constant in conjunction with pointer checking. - -package cgotest - -/* -#include - -#define CheckConstVal 0 - -typedef struct { - int *p; -} CheckConstStruct; - -static void CheckConstFunc(CheckConstStruct *p, int e) { -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func testCheckConst(t *testing.T) { - // The test is that this compiles successfully. - p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0)))) - defer C.free(p) - C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal) -} diff --git a/libgo/misc/cgo/test/complex.go b/libgo/misc/cgo/test/complex.go deleted file mode 100644 index ca0a97d..0000000 --- a/libgo/misc/cgo/test/complex.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -struct { - float x; - _Complex float y; -} cplxAlign = { 3.14, 2.17 }; -*/ -import "C" - -import "testing" - -func TestComplexAlign(t *testing.T) { - if C.cplxAlign.x != 3.14 { - t.Errorf("got %v, expected 3.14", C.cplxAlign.x) - } - if C.cplxAlign.y != 2.17 { - t.Errorf("got %v, expected 2.17", C.cplxAlign.y) - } -} diff --git a/libgo/misc/cgo/test/cthread.go b/libgo/misc/cgo/test/cthread.go deleted file mode 100644 index af44911..0000000 --- a/libgo/misc/cgo/test/cthread.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// extern void doAdd(int, int); -import "C" - -import ( - "runtime" - "sync" - "testing" -) - -var sum struct { - sync.Mutex - i int -} - -//export Add -func Add(x int) { - defer func() { - recover() - }() - sum.Lock() - sum.i += x - sum.Unlock() - var p *int - *p = 2 -} - -func testCthread(t *testing.T) { - if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { - t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add") - } - sum.i = 0 - C.doAdd(10, 6) - - want := 10 * (10 - 1) / 2 * 6 - if sum.i != want { - t.Fatalf("sum=%d, want %d", sum.i, want) - } -} diff --git a/libgo/misc/cgo/test/duplicate_symbol.go b/libgo/misc/cgo/test/duplicate_symbol.go deleted file mode 100644 index 6144271..0000000 --- a/libgo/misc/cgo/test/duplicate_symbol.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains test cases for cgo. - -package cgotest - -/* -int base_symbol = 0; - -#define alias_one base_symbol -#define alias_two base_symbol -*/ -import "C" - -import "fmt" - -func duplicateSymbols() { - fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two) -} diff --git a/libgo/misc/cgo/test/env.go b/libgo/misc/cgo/test/env.go deleted file mode 100644 index b2081b7..0000000 --- a/libgo/misc/cgo/test/env.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include -*/ -import "C" -import ( - "os" - "runtime" - "testing" - "unsafe" -) - -// This is really an os package test but here for convenience. -func testSetEnv(t *testing.T) { - if runtime.GOOS == "windows" { - // Go uses SetEnvironmentVariable on windows. Howerver, - // C runtime takes a *copy* at process startup of thei - // OS environment, and stores it in environ/envp. - // It is this copy that getenv/putenv manipulate. - t.Logf("skipping test") - return - } - const key = "CGO_OS_TEST_KEY" - const val = "CGO_OS_TEST_VALUE" - os.Setenv(key, val) - keyc := C.CString(key) - defer C.free(unsafe.Pointer(keyc)) - v := C.getenv(keyc) - if uintptr(unsafe.Pointer(v)) == 0 { - t.Fatal("getenv returned NULL") - } - vs := C.GoString(v) - if vs != val { - t.Fatalf("getenv() = %q; want %q", vs, val) - } -} diff --git a/libgo/misc/cgo/test/exports.go b/libgo/misc/cgo/test/exports.go deleted file mode 100644 index 71e5dcd..0000000 --- a/libgo/misc/cgo/test/exports.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" -import "runtime" - -//export ReturnIntLong -func ReturnIntLong() (int, C.long) { - return 1, 2 -} - -//export gc -func gc() { - runtime.GC() -} diff --git a/libgo/misc/cgo/test/fpvar.go b/libgo/misc/cgo/test/fpvar.go deleted file mode 100644 index 7aab8ca..0000000 --- a/libgo/misc/cgo/test/fpvar.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains test cases for cgo with function pointer variables. - -package cgotest - -/* -typedef int (*intFunc) (); - -int -bridge_int_func(intFunc f) -{ - return f(); -} - -int fortytwo() -{ - return 42; -} - -*/ -import "C" -import "testing" - -func callBridge(f C.intFunc) int { - return int(C.bridge_int_func(f)) -} - -func callCBridge(f C.intFunc) C.int { - return C.bridge_int_func(f) -} - -func testFpVar(t *testing.T) { - const expected = 42 - f := C.intFunc(C.fortytwo) - res1 := C.bridge_int_func(f) - if r1 := int(res1); r1 != expected { - t.Errorf("got %d, want %d", r1, expected) - } - res2 := callCBridge(f) - if r2 := int(res2); r2 != expected { - t.Errorf("got %d, want %d", r2, expected) - } - r3 := callBridge(f) - if r3 != expected { - t.Errorf("got %d, want %d", r3, expected) - } -} diff --git a/libgo/misc/cgo/test/gcc68255.go b/libgo/misc/cgo/test/gcc68255.go deleted file mode 100644 index 23e103d..0000000 --- a/libgo/misc/cgo/test/gcc68255.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import ( - "testing" - - "./gcc68255" -) - -func testGCC68255(t *testing.T) { - if !gcc68255.F() { - t.Error("C global variable was not initialized") - } -} diff --git a/libgo/misc/cgo/test/gcc68255/a.go b/libgo/misc/cgo/test/gcc68255/a.go deleted file mode 100644 index e106dee..0000000 --- a/libgo/misc/cgo/test/gcc68255/a.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that it's OK to have C code that does nothing other than -// initialize a global variable. This used to fail with gccgo. - -package gcc68255 - -/* -#include "c.h" -*/ -import "C" - -func F() bool { - return C.v != nil -} diff --git a/libgo/misc/cgo/test/gcc68255/c.c b/libgo/misc/cgo/test/gcc68255/c.c deleted file mode 100644 index a4fe193..0000000 --- a/libgo/misc/cgo/test/gcc68255/c.c +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -static void f(void) { -} - -void (*v)(void) = f; diff --git a/libgo/misc/cgo/test/gcc68255/c.h b/libgo/misc/cgo/test/gcc68255/c.h deleted file mode 100644 index 05ecd81..0000000 --- a/libgo/misc/cgo/test/gcc68255/c.h +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -extern void (*v)(void); diff --git a/libgo/misc/cgo/test/helpers.go b/libgo/misc/cgo/test/helpers.go deleted file mode 100644 index f6a822a..0000000 --- a/libgo/misc/cgo/test/helpers.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// const char *greeting = "hello, world"; -import "C" - -import ( - "reflect" - "testing" - "unsafe" -) - -const greeting = "hello, world" - -type testPair struct { - Name string - Got, Want interface{} -} - -var testPairs = []testPair{ - {"GoString", C.GoString(C.greeting), greeting}, - {"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]}, - {"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])}, -} - -func testHelpers(t *testing.T) { - for _, pair := range testPairs { - if !reflect.DeepEqual(pair.Got, pair.Want) { - t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want) - } - } -} diff --git a/libgo/misc/cgo/test/issue10303.go b/libgo/misc/cgo/test/issue10303.go deleted file mode 100644 index 66e2644..0000000 --- a/libgo/misc/cgo/test/issue10303.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 10303. Pointers passed to C were not marked as escaping (bug in cgo). - -package cgotest - -import "runtime" - -/* -typedef int *intptr; - -void setintstar(int *x) { - *x = 1; -} - -void setintptr(intptr x) { - *x = 1; -} - -void setvoidptr(void *x) { - *(int*)x = 1; -} - -typedef struct Struct Struct; -struct Struct { - int *P; -}; - -void setstruct(Struct s) { - *s.P = 1; -} - -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test10303(t *testing.T, n int) { - if runtime.Compiler == "gccgo" { - t.Skip("gccgo permits C pointers on the stack") - } - - // Run at a few different stack depths just to avoid an unlucky pass - // due to variables ending up on different pages. - if n > 0 { - test10303(t, n-1) - } - if t.Failed() { - return - } - var x, y, z, v, si C.int - var s C.Struct - C.setintstar(&x) - C.setintptr(&y) - C.setvoidptr(unsafe.Pointer(&v)) - s.P = &si - C.setstruct(s) - - if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C int* argument on stack") - } - if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C intptr argument on stack") - } - if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C void* argument on stack") - } - if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { - t.Error("C struct field pointer on stack") - } -} diff --git a/libgo/misc/cgo/test/issue11925.go b/libgo/misc/cgo/test/issue11925.go deleted file mode 100644 index c5c8a26..0000000 --- a/libgo/misc/cgo/test/issue11925.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 11925. Structs with zero-length trailing fields are now -// padded by the Go compiler. - -package cgotest - -/* -struct a11925 { - int i; - char a[0]; - char b[0]; -}; - -struct b11925 { - int i; - char a[0]; - char b[]; -}; -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test11925(t *testing.T) { - if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) { - t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{})) - } - if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) { - t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{})) - } -} diff --git a/libgo/misc/cgo/test/issue12030.go b/libgo/misc/cgo/test/issue12030.go deleted file mode 100644 index f863c58..0000000 --- a/libgo/misc/cgo/test/issue12030.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 12030. sprintf is defined in both ntdll and msvcrt, -// Normally we want the one in the msvcrt. - -package cgotest - -/* -#include -#include -void issue12030conv(char *buf, double x) { - sprintf(buf, "d=%g", x); -} -*/ -import "C" - -import ( - "fmt" - "testing" - "unsafe" -) - -func test12030(t *testing.T) { - buf := (*C.char)(C.malloc(256)) - defer C.free(unsafe.Pointer(buf)) - for _, f := range []float64{1.0, 2.0, 3.14} { - C.issue12030conv(buf, C.double(f)) - got := C.GoString(buf) - if want := fmt.Sprintf("d=%g", f); got != want { - t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want) - } - } -} diff --git a/libgo/misc/cgo/test/issue1222.go b/libgo/misc/cgo/test/issue1222.go deleted file mode 100644 index 4868da8..0000000 --- a/libgo/misc/cgo/test/issue1222.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file contains test cases for cgo. - -package cgotest - -/* -// issue 1222 -typedef union { - long align; -} xxpthread_mutex_t; - -struct ibv_async_event { - union { - int x; - } element; -}; - -struct ibv_context { - xxpthread_mutex_t mutex; -}; -*/ -import "C" - -type AsyncEvent struct { - event C.struct_ibv_async_event -} diff --git a/libgo/misc/cgo/test/issue1328.go b/libgo/misc/cgo/test/issue1328.go deleted file mode 100644 index 2401c10..0000000 --- a/libgo/misc/cgo/test/issue1328.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "testing" - -// extern void BackIntoGo(void); -// void IntoC(void); -import "C" - -//export BackIntoGo -func BackIntoGo() { - x := 1 - - for i := 0; i < 10000; i++ { - xvariadic(x) - if x != 1 { - panic("x is not 1?") - } - } -} - -func xvariadic(x ...interface{}) { -} - -func test1328(t *testing.T) { - C.IntoC() -} diff --git a/libgo/misc/cgo/test/issue13402.go b/libgo/misc/cgo/test/issue13402.go deleted file mode 100644 index 3af24c2..0000000 --- a/libgo/misc/cgo/test/issue13402.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" - -var _ C.complexfloat -var _ C.complexdouble diff --git a/libgo/misc/cgo/test/issue13930.go b/libgo/misc/cgo/test/issue13930.go deleted file mode 100644 index c4a08ee..0000000 --- a/libgo/misc/cgo/test/issue13930.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 13930. Test that cgo's multiple-value special form for -// C function calls works in variable declaration statements. - -package cgotest - -// #include -import "C" - -var _, _ = C.abs(0) diff --git a/libgo/misc/cgo/test/issue14838.go b/libgo/misc/cgo/test/issue14838.go deleted file mode 100644 index c8e1681..0000000 --- a/libgo/misc/cgo/test/issue14838.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 14838. add CBytes function - -package cgotest - -/* -#include - -int check_cbytes(char *b, size_t l) { - int i; - for (i = 0; i < l; i++) { - if (b[i] != i) { - return 0; - } - } - return 1; -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func test14838(t *testing.T) { - data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - cData := C.CBytes(data) - defer C.free(cData) - - if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 { - t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:]) - } -} diff --git a/libgo/misc/cgo/test/issue1560.go b/libgo/misc/cgo/test/issue1560.go deleted file mode 100644 index 30f6152..0000000 --- a/libgo/misc/cgo/test/issue1560.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// mysleep returns the absolute start time in ms. -long long mysleep(int seconds); - -// twoSleep returns the absolute start time of the first sleep -// in ms. -long long twoSleep(int); -*/ -import "C" - -import ( - "testing" - "time" -) - -var sleepDone = make(chan int64) - -// parallelSleep returns the absolute difference between the start time -// of the two sleeps. -func parallelSleep(n int) int64 { - t := int64(C.twoSleep(C.int(n))) - <-sleepDone - if t < 0 { - return -t - } - return t -} - -//export BackgroundSleep -func BackgroundSleep(n int32) { - go func() { - sleepDone <- int64(C.mysleep(C.int(n))) - }() -} - -func testParallelSleep(t *testing.T) { - sleepSec := 1 - dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond - t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt) - // bug used to run sleeps in serial, producing a 2*sleepSec-second delay. - // we detect if the start times of those sleeps are > 0.5*sleepSec-second. - if dt >= time.Duration(sleepSec)*time.Second/2 { - t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds()) - } -} diff --git a/libgo/misc/cgo/test/issue1635.go b/libgo/misc/cgo/test/issue1635.go deleted file mode 100644 index 2589927..0000000 --- a/libgo/misc/cgo/test/issue1635.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// Mac OS X's gcc will generate scattered relocation 2/1 for -// this function on Darwin/386, and 8l couldn't handle it. -// this example is in issue 1635 -#include -void scatter() { - void *p = scatter; - printf("scatter = %p\n", p); -} - -// Adding this explicit extern declaration makes this a test for -// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 . -// It used to cause a cgo error when building with GCC 6. -extern int hola; - -// this example is in issue 3253 -int hola = 0; -int testHola() { return hola; } -*/ -import "C" - -import "testing" - -func test1635(t *testing.T) { - C.scatter() - if v := C.hola; v != 0 { - t.Fatalf("C.hola is %d, should be 0", v) - } - if v := C.testHola(); v != 0 { - t.Fatalf("C.testHola() is %d, should be 0", v) - } -} diff --git a/libgo/misc/cgo/test/issue17065.go b/libgo/misc/cgo/test/issue17065.go deleted file mode 100644 index ede30bc..0000000 --- a/libgo/misc/cgo/test/issue17065.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// Test that C symbols larger than a page play nicely with the race detector. -// See issue 17065. - -int ii[65537]; -*/ -import "C" - -import ( - "runtime" - "testing" -) - -var sink C.int - -func test17065(t *testing.T) { - if runtime.GOOS == "darwin" { - t.Skip("broken on darwin; issue 17065") - } - for i := range C.ii { - sink = C.ii[i] - } -} diff --git a/libgo/misc/cgo/test/issue17537.go b/libgo/misc/cgo/test/issue17537.go deleted file mode 100644 index 777104e..0000000 --- a/libgo/misc/cgo/test/issue17537.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 17537. The void* cast introduced by cgo to avoid problems -// with const/volatile qualifiers breaks C preprocessor macros that -// emulate functions. - -package cgotest - -/* -#include - -typedef struct { - int i; -} S17537; - -int I17537(S17537 *p); - -#define I17537(p) ((p)->i) - -// Calling this function used to fail without the cast. -const int F17537(const char **p) { - return **p; -} - -// Calling this function used to trigger an error from the C compiler -// (issue 18298). -void F18298(const void *const *p) { -} - -// Test that conversions between typedefs work as they used to. -typedef const void *T18298_1; -struct S18298 { int i; }; -typedef const struct S18298 *T18298_2; -void G18298(T18298_1 t) { -} -*/ -import "C" - -import "testing" - -func test17537(t *testing.T) { - v := C.S17537{i: 17537} - if got, want := C.I17537(&v), C.int(17537); got != want { - t.Errorf("got %d, want %d", got, want) - } - - p := (*C.char)(C.malloc(1)) - *p = 17 - if got, want := C.F17537(&p), C.int(17); got != want { - t.Errorf("got %d, want %d", got, want) - } - - C.F18298(nil) - var v18298 C.T18298_2 - C.G18298(C.T18298_1(v18298)) -} diff --git a/libgo/misc/cgo/test/issue18126.go b/libgo/misc/cgo/test/issue18126.go deleted file mode 100644 index ac94a66..0000000 --- a/libgo/misc/cgo/test/issue18126.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 18126: cgo check of void function returning errno. - -package cgotest - -/* -#include - -void Issue18126C(void **p) { -} -*/ -import "C" - -import ( - "testing" -) - -func test18126(t *testing.T) { - p := C.malloc(1) - _, err := C.Issue18126C(&p) - C.free(p) - _ = err -} diff --git a/libgo/misc/cgo/test/issue18146.go b/libgo/misc/cgo/test/issue18146.go index 8b7bb77..196d98f 100644 --- a/libgo/misc/cgo/test/issue18146.go +++ b/libgo/misc/cgo/test/issue18146.go @@ -8,8 +8,6 @@ package cgotest -import "C" - import ( "bytes" "crypto/md5" @@ -46,12 +44,12 @@ func test18146(t *testing.T) { switch runtime.GOOS { default: setNproc = false + case "aix": + nproc = 9 case "linux": nproc = 6 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd": nproc = 7 - case "aix": - nproc = 9 } if setNproc { var rlim syscall.Rlimit diff --git a/libgo/misc/cgo/test/issue18720.go b/libgo/misc/cgo/test/issue18720.go deleted file mode 100644 index 3d64003..0000000 --- a/libgo/misc/cgo/test/issue18720.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#define HELLO "hello" -#define WORLD "world" -#define HELLO_WORLD HELLO "\000" WORLD - -struct foo { char c; }; -#define SIZE_OF(x) sizeof(x) -#define SIZE_OF_FOO SIZE_OF(struct foo) -#define VAR1 VAR -#define VAR var -int var = 5; - -#define ADDR &var - -#define CALL fn() -int fn(void) { - return ++var; -} -*/ -import "C" -import "testing" - -func test18720(t *testing.T) { - if got, want := C.HELLO_WORLD, "hello\000world"; got != want { - t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want) - } - - if got, want := C.VAR1, C.int(5); got != want { - t.Errorf("C.VAR1 == %v, expected %v", got, want) - } - - if got, want := *C.ADDR, C.int(5); got != want { - t.Errorf("*C.ADDR == %v, expected %v", got, want) - } - - if got, want := C.CALL, C.int(6); got != want { - t.Errorf("C.CALL == %v, expected %v", got, want) - } - - if got, want := C.CALL, C.int(7); got != want { - t.Errorf("C.CALL == %v, expected %v", got, want) - } - - // Issue 20125. - if got, want := C.SIZE_OF_FOO, 1; got != want { - t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue20129.go b/libgo/misc/cgo/test/issue20129.go deleted file mode 100644 index e69e0e1..0000000 --- a/libgo/misc/cgo/test/issue20129.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -int issue20129 = 0; -typedef void issue20129Void; -issue20129Void issue20129Foo() { - issue20129 = 1; -} -typedef issue20129Void issue20129Void2; -issue20129Void2 issue20129Bar() { - issue20129 = 2; -} -*/ -import "C" -import "testing" - -func test20129(t *testing.T) { - if C.issue20129 != 0 { - t.Fatal("test is broken") - } - C.issue20129Foo() - if C.issue20129 != 1 { - t.Errorf("got %v but expected %v", C.issue20129, 1) - } - C.issue20129Bar() - if C.issue20129 != 2 { - t.Errorf("got %v but expected %v", C.issue20129, 2) - } -} diff --git a/libgo/misc/cgo/test/issue20266.go b/libgo/misc/cgo/test/issue20266.go deleted file mode 100644 index 9f95086..0000000 --- a/libgo/misc/cgo/test/issue20266.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 20266: use -I with a relative path. - -package cgotest - -/* -#cgo CFLAGS: -I issue20266 -Iissue20266 -Ddef20266 -#include "issue20266.h" -*/ -import "C" - -import "testing" - -func test20266(t *testing.T) { - if got, want := C.issue20266, 20266; got != want { - t.Errorf("got %d, want %d", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue20266/issue20266.h b/libgo/misc/cgo/test/issue20266/issue20266.h deleted file mode 100644 index 8d3258e..0000000 --- a/libgo/misc/cgo/test/issue20266/issue20266.h +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#define issue20266 20266 - -#ifndef def20266 -#error "expected def20266 to be defined" -#endif diff --git a/libgo/misc/cgo/test/issue20369.go b/libgo/misc/cgo/test/issue20369.go deleted file mode 100644 index 37b4b78..0000000 --- a/libgo/misc/cgo/test/issue20369.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#define UINT64_MAX 18446744073709551615ULL -*/ -import "C" -import ( - "math" - "testing" -) - -func test20369(t *testing.T) { - if C.UINT64_MAX != math.MaxUint64 { - t.Fatalf("got %v, want %v", uint64(C.UINT64_MAX), uint64(math.MaxUint64)) - } -} diff --git a/libgo/misc/cgo/test/issue20910.go b/libgo/misc/cgo/test/issue20910.go deleted file mode 100644 index 69d7d92..0000000 --- a/libgo/misc/cgo/test/issue20910.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -//void callMulti(void); -import "C" - -import "testing" - -//export multi -func multi() (*C.char, C.int) { - return C.CString("multi"), 0 -} - -func test20910(t *testing.T) { - C.callMulti() -} diff --git a/libgo/misc/cgo/test/issue21668.go b/libgo/misc/cgo/test/issue21668.go deleted file mode 100644 index f15b920..0000000 --- a/libgo/misc/cgo/test/issue21668.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Fail to guess the kind of the constant "x". -// No runtime test; just make sure it compiles. - -package cgotest - -// const int x = 42; -import "C" - -var issue21668_X = C.x diff --git a/libgo/misc/cgo/test/issue21708.go b/libgo/misc/cgo/test/issue21708.go deleted file mode 100644 index d413e3c5..0000000 --- a/libgo/misc/cgo/test/issue21708.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// #include -// #define CAST_TO_INT64 (int64_t)(-1) -import "C" -import "testing" - -func test21708(t *testing.T) { - if got, want := C.CAST_TO_INT64, -1; got != want { - t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue21809.go b/libgo/misc/cgo/test/issue21809.go deleted file mode 100644 index a3a6b88..0000000 --- a/libgo/misc/cgo/test/issue21809.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Issue 21809. Compile C `typedef` to go type aliases. - -// typedef long MySigned_t; -// /* tests alias-to-alias */ -// typedef MySigned_t MySigned2_t; -// -// long takes_long(long x) { return x * x; } -// MySigned_t takes_typedef(MySigned_t x) { return x * x; } -import "C" - -import "testing" - -func test21809(t *testing.T) { - longVar := C.long(3) - typedefVar := C.MySigned_t(4) - typedefTypedefVar := C.MySigned2_t(5) - - // all three should be considered identical to `long` - if ret := C.takes_long(longVar); ret != 9 { - t.Errorf("got %v but expected %v", ret, 9) - } - if ret := C.takes_long(typedefVar); ret != 16 { - t.Errorf("got %v but expected %v", ret, 16) - } - if ret := C.takes_long(typedefTypedefVar); ret != 25 { - t.Errorf("got %v but expected %v", ret, 25) - } - - // They should also be identical to the typedef'd type - if ret := C.takes_typedef(longVar); ret != 9 { - t.Errorf("got %v but expected %v", ret, 9) - } - if ret := C.takes_typedef(typedefVar); ret != 16 { - t.Errorf("got %v but expected %v", ret, 16) - } - if ret := C.takes_typedef(typedefTypedefVar); ret != 25 { - t.Errorf("got %v but expected %v", ret, 25) - } -} diff --git a/libgo/misc/cgo/test/issue22958.go b/libgo/misc/cgo/test/issue22958.go deleted file mode 100644 index a5f058f..0000000 --- a/libgo/misc/cgo/test/issue22958.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Test handling of bitfields. - -/* -typedef struct { - unsigned long long f8 : 8; - unsigned long long f16 : 16; - unsigned long long f24 : 24; - unsigned long long f32 : 32; - unsigned long long f40 : 40; - unsigned long long f48 : 48; - unsigned long long f56 : 56; - unsigned long long f64 : 64; -} issue22958Type; -*/ -import "C" - -// Nothing to run, just make sure this compiles. -var Vissue22958 C.issue22958Type diff --git a/libgo/misc/cgo/test/issue23356.go b/libgo/misc/cgo/test/issue23356.go deleted file mode 100644 index 1c39012..0000000 --- a/libgo/misc/cgo/test/issue23356.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// int a(void) { return 5; }; -// int r(void) { return 3; }; -import "C" -import "testing" - -func test23356(t *testing.T) { - if got, want := C.a(), C.int(5); got != want { - t.Errorf("C.a() == %v, expected %v", got, want) - } - if got, want := C.r(), C.int(3); got != want { - t.Errorf("C.r() == %v, expected %v", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue23555.go b/libgo/misc/cgo/test/issue23555.go deleted file mode 100644 index 5fa44e6..0000000 --- a/libgo/misc/cgo/test/issue23555.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that we can have two identical cgo packages in a single binary. -// No runtime test; just make sure it compiles. - -package cgotest - -import _ "./issue23555a" -import _ "./issue23555b" diff --git a/libgo/misc/cgo/test/issue23555a/a.go b/libgo/misc/cgo/test/issue23555a/a.go deleted file mode 100644 index cb6626b..0000000 --- a/libgo/misc/cgo/test/issue23555a/a.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue23555 - -// #include -import "C" - -func X() { - C.free(C.malloc(10)) -} diff --git a/libgo/misc/cgo/test/issue23555b/a.go b/libgo/misc/cgo/test/issue23555b/a.go deleted file mode 100644 index cb6626b..0000000 --- a/libgo/misc/cgo/test/issue23555b/a.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue23555 - -// #include -import "C" - -func X() { - C.free(C.malloc(10)) -} diff --git a/libgo/misc/cgo/test/issue23720.go b/libgo/misc/cgo/test/issue23720.go deleted file mode 100644 index 934fff3..0000000 --- a/libgo/misc/cgo/test/issue23720.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that we can pass compatible typedefs. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -typedef int *issue23720A; - -typedef const int *issue23720B; - -void issue23720F(issue23720B a) {} -*/ -import "C" - -func Issue23720F() { - var x C.issue23720A - C.issue23720F(x) -} diff --git a/libgo/misc/cgo/test/issue24161_darwin_test.go b/libgo/misc/cgo/test/issue24161_darwin_test.go deleted file mode 100644 index 48072ff..0000000 --- a/libgo/misc/cgo/test/issue24161_darwin_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// See issue21897.go and golang.org/issue/26475 for why this is -// skipped in race mode. -// -// TODO(austin): Once support for macOS 10.10 is dropped, remove the -// race constraint. See golang.org/issue/26513. - -// +build !race - -package cgotest - -import ( - "testing" - - "./issue24161arg" - "./issue24161e0" - "./issue24161e1" - "./issue24161e2" - "./issue24161res" -) - -func Test24161Arg(t *testing.T) { - issue24161arg.Test(t) -} -func Test24161Res(t *testing.T) { - issue24161res.Test(t) -} -func Test24161Example0(t *testing.T) { - issue24161e0.Test(t) -} -func Test24161Example1(t *testing.T) { - issue24161e1.Test(t) -} -func Test24161Example2(t *testing.T) { - issue24161e2.Test(t) -} diff --git a/libgo/misc/cgo/test/issue24161arg/def.go b/libgo/misc/cgo/test/issue24161arg/def.go deleted file mode 100644 index d33479a..0000000 --- a/libgo/misc/cgo/test/issue24161arg/def.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161arg - -/* -#cgo LDFLAGS: -framework CoreFoundation -#include -*/ -import "C" - -func test24161array() C.CFArrayRef { - return C.CFArrayCreate(0, nil, 0, nil) -} diff --git a/libgo/misc/cgo/test/issue24161arg/use.go b/libgo/misc/cgo/test/issue24161arg/use.go deleted file mode 100644 index 3e74944..0000000 --- a/libgo/misc/cgo/test/issue24161arg/use.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161arg - -/* -#cgo LDFLAGS: -framework CoreFoundation -#include -*/ -import "C" -import "testing" - -func Test(t *testing.T) { - a := test24161array() - C.CFArrayCreateCopy(0, a) -} diff --git a/libgo/misc/cgo/test/issue24161e0/main.go b/libgo/misc/cgo/test/issue24161e0/main.go deleted file mode 100644 index cbc1dee..0000000 --- a/libgo/misc/cgo/test/issue24161e0/main.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161e0 - -/* -#cgo CFLAGS: -x objective-c -#cgo LDFLAGS: -framework CoreFoundation -framework Security -#include -#include -#include -#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 - typedef CFStringRef SecKeyAlgorithm; - static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} - #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() - static SecKeyAlgorithm foo(void){return NULL;} -#endif -*/ -import "C" -import "testing" - -func f1() { - C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) -} - -func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/issue24161e1/main.go b/libgo/misc/cgo/test/issue24161e1/main.go deleted file mode 100644 index eb48fc0..0000000 --- a/libgo/misc/cgo/test/issue24161e1/main.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161e1 - -/* -#cgo CFLAGS: -x objective-c -#cgo LDFLAGS: -framework CoreFoundation -framework Security -#include -#include -#include -#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 - typedef CFStringRef SecKeyAlgorithm; - static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} - #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() - static SecKeyAlgorithm foo(void){return NULL;} -#endif -*/ -import "C" -import ( - "fmt" - "testing" -) - -func f1() { - C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) -} - -func f2(e C.CFErrorRef) { - if desc := C.CFErrorCopyDescription(e); desc != 0 { - fmt.Println(desc) - } -} - -func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/issue24161e2/main.go b/libgo/misc/cgo/test/issue24161e2/main.go deleted file mode 100644 index 1951c86..0000000 --- a/libgo/misc/cgo/test/issue24161e2/main.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161e2 - -/* -#cgo CFLAGS: -x objective-c -#cgo LDFLAGS: -framework CoreFoundation -framework Security -#include -#include -#include -#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 - typedef CFStringRef SecKeyAlgorithm; - static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} - #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() - static SecKeyAlgorithm foo(void){return NULL;} -#endif -*/ -import "C" -import ( - "fmt" - "testing" -) - -var _ C.CFStringRef - -func f1() { - C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) -} - -func f2(e C.CFErrorRef) { - if desc := C.CFErrorCopyDescription(e); desc != 0 { - fmt.Println(desc) - } -} - -func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/issue24161res/restype.go b/libgo/misc/cgo/test/issue24161res/restype.go deleted file mode 100644 index e5719f2..0000000 --- a/libgo/misc/cgo/test/issue24161res/restype.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package issue24161res - -/* -#cgo LDFLAGS: -framework CoreFoundation -#include -*/ -import "C" -import ( - "reflect" - "testing" -) - -func Test(t *testing.T) { - if k := reflect.TypeOf(C.CFArrayCreate(0, nil, 0, nil)).Kind(); k != reflect.Uintptr { - t.Fatalf("bad kind %s\n", k) - } -} diff --git a/libgo/misc/cgo/test/issue24206.go b/libgo/misc/cgo/test/issue24206.go deleted file mode 100644 index 5fec68e..0000000 --- a/libgo/misc/cgo/test/issue24206.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build amd64,linux - -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Test that C.GoString uses IndexByte in safe manner. - -/* -#include - -// Returns string with null byte at the last valid address -char* dangerousString1() { - int pageSize = 4096; - char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); - mprotect(data + pageSize,pageSize,PROT_NONE); - int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte - int i = start; - for (; i < pageSize; i++) { - data[i] = 'x'; - } - data[pageSize -1 ] = 0; - return data+start; -} - -char* dangerousString2() { - int pageSize = 4096; - char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); - mprotect(data + 2 * pageSize,pageSize,PROT_NONE); - int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte - int i = start; - for (; i < 2 * pageSize; i++) { - data[i] = 'x'; - } - data[2*pageSize -1 ] = 0; - return data+start; -} -*/ -import "C" - -import ( - "testing" -) - -func test24206(t *testing.T) { - if l := len(C.GoString(C.dangerousString1())); l != 123 { - t.Errorf("Incorrect string length - got %d, want 123", l) - } - if l := len(C.GoString(C.dangerousString2())); l != 4096+123 { - t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123) - } -} diff --git a/libgo/misc/cgo/test/issue24206_generic.go b/libgo/misc/cgo/test/issue24206_generic.go deleted file mode 100644 index 27c4d65..0000000 --- a/libgo/misc/cgo/test/issue24206_generic.go +++ /dev/null @@ -1,13 +0,0 @@ -// +build !amd64 !linux - -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "testing" - -func test24206(t *testing.T) { - t.Skip("Skipping on non-amd64 or non-linux system") -} diff --git a/libgo/misc/cgo/test/issue2462.go b/libgo/misc/cgo/test/issue2462.go deleted file mode 100644 index febca1e..0000000 --- a/libgo/misc/cgo/test/issue2462.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" - -//export exportbyte -func exportbyte() byte { - return 0 -} - -//export exportbool -func exportbool() bool { - return false -} - -//export exportrune -func exportrune() rune { - return 0 -} - -//export exporterror -func exporterror() error { - return nil -} - -//export exportint -func exportint() int { - return 0 -} - -//export exportuint -func exportuint() uint { - return 0 -} - -//export exportuintptr -func exportuintptr() uintptr { - return (uintptr)(0) -} - -//export exportint8 -func exportint8() int8 { - return 0 -} - -//export exportuint8 -func exportuint8() uint8 { - return 0 -} - -//export exportint16 -func exportint16() int16 { - return 0 -} - -//export exportuint16 -func exportuint16() uint16 { - return 0 -} - -//export exportint32 -func exportint32() int32 { - return 0 -} - -//export exportuint32 -func exportuint32() uint32 { - return 0 -} - -//export exportint64 -func exportint64() int64 { - return 0 -} - -//export exportuint64 -func exportuint64() uint64 { - return 0 -} - -//export exportfloat32 -func exportfloat32() float32 { - return 0 -} - -//export exportfloat64 -func exportfloat64() float64 { - return 0 -} - -//export exportcomplex64 -func exportcomplex64() complex64 { - return 0 -} - -//export exportcomplex128 -func exportcomplex128() complex128 { - return 0 -} diff --git a/libgo/misc/cgo/test/issue25143.go b/libgo/misc/cgo/test/issue25143.go deleted file mode 100644 index 607bfe4..0000000 --- a/libgo/misc/cgo/test/issue25143.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" -import "testing" - -func issue25143sum(ns ...C.int) C.int { - total := C.int(0) - for _, n := range ns { - total += n - } - return total -} - -func test25143(t *testing.T) { - if got, want := issue25143sum(1, 2, 3), C.int(6); got != want { - t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue26066.go b/libgo/misc/cgo/test/issue26066.go deleted file mode 100644 index 21028e7..0000000 --- a/libgo/misc/cgo/test/issue26066.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Wrong type of constant with GCC 8 and newer. - -package cgotest - -// const unsigned long long int issue26066 = (const unsigned long long) -1; -import "C" - -import "testing" - -func test26066(t *testing.T) { - var i = int64(C.issue26066) - if i != -1 { - t.Errorf("got %d, want -1", i) - } -} diff --git a/libgo/misc/cgo/test/issue26213/jni.h b/libgo/misc/cgo/test/issue26213/jni.h deleted file mode 100644 index 0c76979..0000000 --- a/libgo/misc/cgo/test/issue26213/jni.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// It's going to be hard to include a whole real JVM to test this. -// So we'll simulate a really easy JVM using just the parts we need. - -// This is the relevant part of jni.h. - -// On Android NDK16, jobject is defined like this in C and C++ -typedef void* jobject; - -typedef jobject jclass; -typedef jobject jthrowable; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; -typedef jarray jobjectArray; - -typedef jobject jweak; - -// Note: jvalue is already a non-pointer type due to it being a C union. diff --git a/libgo/misc/cgo/test/issue26213/test26213.go b/libgo/misc/cgo/test/issue26213/test26213.go deleted file mode 100644 index 5d1f637..0000000 --- a/libgo/misc/cgo/test/issue26213/test26213.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue26213 - -/* -#include "jni.h" -*/ -import "C" -import ( - "testing" -) - -func Test26213(t *testing.T) { - var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. - _ = x1 - var x2 C.jclass = 0 - _ = x2 - var x3 C.jthrowable = 0 - _ = x3 - var x4 C.jstring = 0 - _ = x4 - var x5 C.jarray = 0 - _ = x5 - var x6 C.jbooleanArray = 0 - _ = x6 - var x7 C.jbyteArray = 0 - _ = x7 - var x8 C.jcharArray = 0 - _ = x8 - var x9 C.jshortArray = 0 - _ = x9 - var x10 C.jintArray = 0 - _ = x10 - var x11 C.jlongArray = 0 - _ = x11 - var x12 C.jfloatArray = 0 - _ = x12 - var x13 C.jdoubleArray = 0 - _ = x13 - var x14 C.jobjectArray = 0 - _ = x14 - var x15 C.jweak = 0 - _ = x15 -} diff --git a/libgo/misc/cgo/test/issue26430.go b/libgo/misc/cgo/test/issue26430.go deleted file mode 100644 index 3ad5420..0000000 --- a/libgo/misc/cgo/test/issue26430.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 26430: incomplete typedef leads to inconsistent typedefs error. -// No runtime test; just make sure it compiles. - -package cgotest - -import _ "./issue26430" diff --git a/libgo/misc/cgo/test/issue26430/a.go b/libgo/misc/cgo/test/issue26430/a.go deleted file mode 100644 index fbaa46b..0000000 --- a/libgo/misc/cgo/test/issue26430/a.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package a - -// typedef struct S ST; -// static ST* F() { return 0; } -import "C" - -func F1() { - C.F() -} diff --git a/libgo/misc/cgo/test/issue26430/b.go b/libgo/misc/cgo/test/issue26430/b.go deleted file mode 100644 index a7c527c..0000000 --- a/libgo/misc/cgo/test/issue26430/b.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package a - -// typedef struct S ST; -// struct S { int f; }; -import "C" - -func F2(p *C.ST) { - p.f = 1 -} diff --git a/libgo/misc/cgo/test/issue26517.go b/libgo/misc/cgo/test/issue26517.go deleted file mode 100644 index c1bf1c9..0000000 --- a/libgo/misc/cgo/test/issue26517.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Introduce two pointer types which are distinct, but have the same -// base type. Make sure that both of those pointer types get resolved -// correctly. Before the fix for 26517 if one of these pointer types -// was resolved before the other one was processed, the second one -// would never be resolved. -// Before this issue was fixed this test failed on Windows, -// where va_list expands to a named char* type. - -/* -#include -typedef va_list TypeOne; -typedef char *TypeTwo; -*/ -import "C" - -var a C.TypeOne -var b C.TypeTwo diff --git a/libgo/misc/cgo/test/issue26743.go b/libgo/misc/cgo/test/issue26743.go deleted file mode 100644 index 35c8473..0000000 --- a/libgo/misc/cgo/test/issue26743.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 26743: typedef of uint leads to inconsistent typedefs error. -// No runtime test; just make sure it compiles. - -package cgotest - -import _ "./issue26743" diff --git a/libgo/misc/cgo/test/issue26743/a.go b/libgo/misc/cgo/test/issue26743/a.go deleted file mode 100644 index a3df179..0000000 --- a/libgo/misc/cgo/test/issue26743/a.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue26743 - -// typedef unsigned int uint; -// int C1(uint x) { return x; } -import "C" - -var V1 = C.C1(0) diff --git a/libgo/misc/cgo/test/issue26743/b.go b/libgo/misc/cgo/test/issue26743/b.go deleted file mode 100644 index c5f1ae4..0000000 --- a/libgo/misc/cgo/test/issue26743/b.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue26743 - -import "C" - -var V2 C.uint diff --git a/libgo/misc/cgo/test/issue27054/egl.h b/libgo/misc/cgo/test/issue27054/egl.h deleted file mode 100644 index 33a759e..0000000 --- a/libgo/misc/cgo/test/issue27054/egl.h +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This is the relevant part of EGL/egl.h. - -typedef void *EGLDisplay; diff --git a/libgo/misc/cgo/test/issue27054/test27054.go b/libgo/misc/cgo/test/issue27054/test27054.go deleted file mode 100644 index 186f5bd..0000000 --- a/libgo/misc/cgo/test/issue27054/test27054.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package issue27054 - -/* -#include "egl.h" -*/ -import "C" -import ( - "testing" -) - -func Test27054(t *testing.T) { - var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type. -} diff --git a/libgo/misc/cgo/test/issue27340.go b/libgo/misc/cgo/test/issue27340.go deleted file mode 100644 index f8c8a87..0000000 --- a/libgo/misc/cgo/test/issue27340.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Failed to resolve typedefs consistently. -// No runtime test; just make sure it compiles. - -package cgotest - -import "./issue27340" - -var issue27340Var = issue27340.Issue27340GoFunc diff --git a/libgo/misc/cgo/test/issue27340/a.go b/libgo/misc/cgo/test/issue27340/a.go deleted file mode 100644 index f5b120c..0000000 --- a/libgo/misc/cgo/test/issue27340/a.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Failed to resolve typedefs consistently. -// No runtime test; just make sure it compiles. -// In separate directory to isolate #pragma GCC diagnostic. - -package issue27340 - -// We use the #pragma to avoid a compiler warning about incompatible -// pointer types, because we generate code passing a struct ptr rather -// than using the typedef. This warning is expected and does not break -// a normal build. -// We can only disable -Wincompatible-pointer-types starting with GCC 5. - -// #if __GNU_MAJOR__ >= 5 -// -// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" -// -// typedef struct { -// int a; -// } issue27340Struct, *issue27340Ptr; -// -// static void issue27340CFunc(issue27340Ptr p) {} -// -// #else /* _GNU_MAJOR_ < 5 */ -// -// typedef struct { -// int a; -// } issue27340Struct; -// -// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; } -// -// static void issue27340CFunc(issue27340Struct *p) {} -// #endif /* _GNU_MAJOR_ < 5 */ -import "C" - -func Issue27340GoFunc() { - var s C.issue27340Struct - C.issue27340CFunc(C.issue27340Ptr(&s)) -} diff --git a/libgo/misc/cgo/test/issue28545.go b/libgo/misc/cgo/test/issue28545.go deleted file mode 100644 index 8419b89..0000000 --- a/libgo/misc/cgo/test/issue28545.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Failed to add type conversion for negative constant. -// Issue 28772: Failed to add type conversion for Go constant set to C constant. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -#include - -#define issue28772Constant 1 - -static void issue28545F(char **p, int n, complex double a) {} -*/ -import "C" - -const issue28772Constant = C.issue28772Constant - -func issue28545G(p **C.char) { - C.issue28545F(p, -1, (0)) - C.issue28545F(p, 2+3, complex(1, 1)) - C.issue28545F(p, issue28772Constant, issue28772Constant2) -} diff --git a/libgo/misc/cgo/test/issue28772.go b/libgo/misc/cgo/test/issue28772.go deleted file mode 100644 index bed786b..0000000 --- a/libgo/misc/cgo/test/issue28772.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Constants didn't work if defined in different source file. - -// #define issue28772Constant2 2 -import "C" - -const issue28772Constant2 = C.issue28772Constant2 diff --git a/libgo/misc/cgo/test/issue28896.go b/libgo/misc/cgo/test/issue28896.go deleted file mode 100644 index 8796040f..0000000 --- a/libgo/misc/cgo/test/issue28896.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo was incorrectly adding padding after a packed struct. - -package cgotest - -/* -#include -#include -#include - -typedef struct { - void *f1; - uint32_t f2; -} __attribute__((__packed__)) innerPacked; - -typedef struct { - innerPacked g1; - uint64_t g2; -} outerPacked; - -typedef struct { - void *f1; - uint32_t f2; -} innerUnpacked; - -typedef struct { - innerUnpacked g1; - uint64_t g2; -} outerUnpacked; - -size_t offset(int x) { - switch (x) { - case 0: - return offsetof(innerPacked, f2); - case 1: - return offsetof(outerPacked, g2); - case 2: - return offsetof(innerUnpacked, f2); - case 3: - return offsetof(outerUnpacked, g2); - default: - abort(); - } -} -*/ -import "C" - -import ( - "testing" - "unsafe" -) - -func offset(i int) uintptr { - var pi C.innerPacked - var po C.outerPacked - var ui C.innerUnpacked - var uo C.outerUnpacked - switch i { - case 0: - return unsafe.Offsetof(pi.f2) - case 1: - return unsafe.Offsetof(po.g2) - case 2: - return unsafe.Offsetof(ui.f2) - case 3: - return unsafe.Offsetof(uo.g2) - default: - panic("can't happen") - } -} - -func test28896(t *testing.T) { - for i := 0; i < 4; i++ { - c := uintptr(C.offset(C.int(i))) - g := offset(i) - if c != g { - t.Errorf("%d: C: %d != Go %d", i, c, g) - } - } -} diff --git a/libgo/misc/cgo/test/issue29383.go b/libgo/misc/cgo/test/issue29383.go deleted file mode 100644 index 462c9a3..0000000 --- a/libgo/misc/cgo/test/issue29383.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo's /*line*/ comments failed when inserted after '/', -// because the result looked like a "//" comment. -// No runtime test; just make sure it compiles. - -package cgotest - -// #include -import "C" - -func Issue29383(n, size uint) int { - if ^C.size_t(0)/C.size_t(n) < C.size_t(size) { - return 0 - } - return 0 -} diff --git a/libgo/misc/cgo/test/issue29748.go b/libgo/misc/cgo/test/issue29748.go deleted file mode 100644 index 8229b3b..0000000 --- a/libgo/misc/cgo/test/issue29748.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Error handling a struct initializer that requires pointer checking. -// Compilation test only, nothing to run. - -package cgotest - -// typedef struct { char **p; } S29748; -// static int f29748(S29748 *p) { return 0; } -import "C" - -var Vissue29748 = C.f29748(&C.S29748{ - nil, -}) - -func Fissue299748() { - C.f29748(&C.S29748{ - nil, - }) -} diff --git a/libgo/misc/cgo/test/issue29781.go b/libgo/misc/cgo/test/issue29781.go deleted file mode 100644 index 0fd8c08..0000000 --- a/libgo/misc/cgo/test/issue29781.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Error with newline inserted into constant expression. -// Compilation test only, nothing to run. - -package cgotest - -// static void issue29781F(char **p, int n) {} -// #define ISSUE29781C 0 -import "C" - -func issue29781G() { - var p *C.char - C.issue29781F(&p, C.ISSUE29781C+1) -} diff --git a/libgo/misc/cgo/test/issue30065.go b/libgo/misc/cgo/test/issue30065.go deleted file mode 100644 index 396d437..0000000 --- a/libgo/misc/cgo/test/issue30065.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Don't make a private copy of an array when taking the address of an -// element. - -package cgotest - -// #include -import "C" - -import ( - "testing" - "unsafe" -) - -func test30065(t *testing.T) { - var a [256]byte - b := []byte("a") - C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1) - if a[0] != 'a' { - t.Errorf("&a failed: got %c, want %c", a[0], 'a') - } - - b = []byte("b") - C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1) - if a[0] != 'b' { - t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b') - } - - d := make([]byte, 256) - b = []byte("c") - C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1) - if d[0] != 'c' { - t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c') - } -} diff --git a/libgo/misc/cgo/test/issue3250.go b/libgo/misc/cgo/test/issue3250.go deleted file mode 100644 index f85c16b..0000000 --- a/libgo/misc/cgo/test/issue3250.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !windows - -package cgotest - -/* -#include -#include -#include -#include - -static void *thread(void *p) { - const int M = 100; - int i; - (void)p; - for (i = 0; i < M; i++) { - pthread_kill(pthread_self(), SIGCHLD); - usleep(rand() % 20 + 5); - } - return NULL; -} -void testSendSIG() { - const int N = 20; - int i; - pthread_t tid[N]; - for (i = 0; i < N; i++) { - usleep(rand() % 200 + 100); - pthread_create(&tid[i], 0, thread, NULL); - } - for (i = 0; i < N; i++) - pthread_join(tid[i], 0); -} -*/ -import "C" - -import ( - "os" - "os/signal" - "syscall" - "testing" - "time" -) - -func test3250(t *testing.T) { - t.Skip("skipped, see golang.org/issue/5885") - const ( - thres = 1 - sig = syscall.SIGCHLD - ) - type result struct { - n int - sig os.Signal - } - var ( - sigCh = make(chan os.Signal, 10) - waitStart = make(chan struct{}) - waitDone = make(chan result) - ) - - signal.Notify(sigCh, sig) - - go func() { - n := 0 - alarm := time.After(time.Second * 3) - for { - select { - case <-waitStart: - waitStart = nil - case v := <-sigCh: - n++ - if v != sig || n > thres { - waitDone <- result{n, v} - return - } - case <-alarm: - waitDone <- result{n, sig} - return - } - } - }() - - waitStart <- struct{}{} - C.testSendSIG() - r := <-waitDone - if r.sig != sig { - t.Fatalf("received signal %v, but want %v", r.sig, sig) - } - t.Logf("got %d signals\n", r.n) - if r.n <= thres { - t.Fatalf("expected more than %d", thres) - } -} diff --git a/libgo/misc/cgo/test/issue3250w.go b/libgo/misc/cgo/test/issue3250w.go deleted file mode 100644 index c2193aa..0000000 --- a/libgo/misc/cgo/test/issue3250w.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows - -package cgotest - -import "testing" - -func test3250(t *testing.T) {} diff --git a/libgo/misc/cgo/test/issue3261.go b/libgo/misc/cgo/test/issue3261.go deleted file mode 100644 index 7137569..0000000 --- a/libgo/misc/cgo/test/issue3261.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// libgcc on ARM might be compiled as thumb code, but our 5l -// can't handle that, so we have to disable this test on arm. -#ifdef __ARMEL__ -#include -int vabs(int x) { - puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library."); - return (x < 0) ? -x : x; -} -#elif defined(__arm64__) && defined(__clang__) -#include -int vabs(int x) { - puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc."); - return (x < 0) ? -x : x; -} -#else -int __absvsi2(int); // dummy prototype for libgcc function -// we shouldn't name the function abs, as gcc might use -// the builtin one. -int vabs(int x) { return __absvsi2(x); } -#endif -*/ -import "C" - -import "testing" - -func testLibgcc(t *testing.T) { - var table = []struct { - in, out C.int - }{ - {0, 0}, - {1, 1}, - {-42, 42}, - {1000300, 1000300}, - {1 - 1<<31, 1<<31 - 1}, - } - for _, v := range table { - if o := C.vabs(v.in); o != v.out { - t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out) - return - } - } -} diff --git a/libgo/misc/cgo/test/issue3729.go b/libgo/misc/cgo/test/issue3729.go deleted file mode 100644 index 947b90a..0000000 --- a/libgo/misc/cgo/test/issue3729.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 3729: cmd/cgo: access errno from void C function -// void f(void) returns [0]byte, error in Go world. - -// +build !windows - -package cgotest - -/* -#include - -void g(void) { - errno = E2BIG; -} - -// try to pass some non-trivial arguments to function g2 -const char _expA = 0x42; -const float _expB = 3.14159; -const short _expC = 0x55aa; -const int _expD = 0xdeadbeef; -void g2(int x, char a, float b, short c, int d) { - if (a == _expA && b == _expB && c == _expC && d == _expD) - errno = x; - else - errno = -1; -} -*/ -import "C" - -import ( - "syscall" - "testing" -) - -func test3729(t *testing.T) { - _, e := C.g() - if e != syscall.E2BIG { - t.Errorf("got %q, expect %q", e, syscall.E2BIG) - } - _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) - if e != syscall.EINVAL { - t.Errorf("got %q, expect %q", e, syscall.EINVAL) - } -} diff --git a/libgo/misc/cgo/test/issue3729w.go b/libgo/misc/cgo/test/issue3729w.go deleted file mode 100644 index 69296b5..0000000 --- a/libgo/misc/cgo/test/issue3729w.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 3729: cmd/cgo: access errno from void C function -// void f(void) returns [0]byte, error in Go world. - -// +build windows - -package cgotest - -import "testing" - -func test3729(t *testing.T) { - t.Log("skip errno test on Windows") -} diff --git a/libgo/misc/cgo/test/issue3741.go b/libgo/misc/cgo/test/issue3741.go deleted file mode 100644 index 314038c..0000000 --- a/libgo/misc/cgo/test/issue3741.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "C" - -//export exportSliceIn -func exportSliceIn(s []byte) bool { - return len(s) == cap(s) -} - -//export exportSliceOut -func exportSliceOut() []byte { - return []byte{1} -} - -//export exportSliceInOut -func exportSliceInOut(s []byte) []byte { - return s -} diff --git a/libgo/misc/cgo/test/issue3775.go b/libgo/misc/cgo/test/issue3775.go deleted file mode 100644 index 5aca760..0000000 --- a/libgo/misc/cgo/test/issue3775.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build !android - -package cgotest - -/* -void lockOSThreadCallback(void); -inline static void lockOSThreadC(void) -{ - lockOSThreadCallback(); -} -int usleep(unsigned usec); -*/ -import "C" - -import ( - "runtime" - "testing" -) - -func init() { - // Same as test3775 but run during init so that - // there are two levels of internal runtime lock - // (1 for init, 1 for cgo). - // This would have been broken by CL 11663043. - C.lockOSThreadC() -} - -func test3775(t *testing.T) { - // Used to panic because of the UnlockOSThread below. - C.lockOSThreadC() -} - -//export lockOSThreadCallback -func lockOSThreadCallback() { - runtime.LockOSThread() - runtime.UnlockOSThread() - go C.usleep(10000) - runtime.Gosched() -} diff --git a/libgo/misc/cgo/test/issue3945.go b/libgo/misc/cgo/test/issue3945.go deleted file mode 100644 index 2f9fe23..0000000 --- a/libgo/misc/cgo/test/issue3945.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Test that cgo reserves enough stack space during cgo call. -// See https://golang.org/issue/3945 for details. - -// #include -// -// void say() { -// printf("%s from C\n", "hello"); -// } -// -import "C" - -import "testing" - -func testPrintf(t *testing.T) { - C.say() -} diff --git a/libgo/misc/cgo/test/issue4054a.go b/libgo/misc/cgo/test/issue4054a.go deleted file mode 100644 index 2abdac5..0000000 --- a/libgo/misc/cgo/test/issue4054a.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -typedef enum { - A = 0, - B, - C, - D, - E, - F, - G, - H, - I, - J, -} issue4054a; -*/ -import "C" - -var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} diff --git a/libgo/misc/cgo/test/issue4054b.go b/libgo/misc/cgo/test/issue4054b.go deleted file mode 100644 index 048964c..0000000 --- a/libgo/misc/cgo/test/issue4054b.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -typedef enum { - A = 0, - B, - C, - D, - E, - F, - G, - H, - I, - J, -} issue4054b; -*/ -import "C" - -var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} diff --git a/libgo/misc/cgo/test/issue4339.go b/libgo/misc/cgo/test/issue4339.go deleted file mode 100644 index 3715fde..0000000 --- a/libgo/misc/cgo/test/issue4339.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -// We've historically permitted #include <>, so test it here. Issue 29333. -#include -*/ -import "C" - -import "testing" - -func test4339(t *testing.T) { - C.handle4339(&C.exported4339) -} diff --git a/libgo/misc/cgo/test/issue4417.go b/libgo/misc/cgo/test/issue4417.go deleted file mode 100644 index 9b18287..0000000 --- a/libgo/misc/cgo/test/issue4417.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 4417: cmd/cgo: bool alignment/padding issue. -// bool alignment is wrong and causing wrong arguments when calling functions. -// - -package cgotest - -/* -#include - -static int c_bool(bool a, bool b, int c, bool d, bool e) { - return c; -} -*/ -import "C" -import "testing" - -func testBoolAlign(t *testing.T) { - b := C.c_bool(true, true, 10, true, false) - if b != 10 { - t.Fatalf("found %d expected 10\n", b) - } - b = C.c_bool(true, true, 5, true, true) - if b != 5 { - t.Fatalf("found %d expected 5\n", b) - } - b = C.c_bool(true, true, 3, true, false) - if b != 3 { - t.Fatalf("found %d expected 3\n", b) - } - b = C.c_bool(false, false, 1, true, false) - if b != 1 { - t.Fatalf("found %d expected 1\n", b) - } - b = C.c_bool(false, true, 200, true, false) - if b != 200 { - t.Fatalf("found %d expected 200\n", b) - } -} diff --git a/libgo/misc/cgo/test/issue4857.go b/libgo/misc/cgo/test/issue4857.go deleted file mode 100644 index b18979b..0000000 --- a/libgo/misc/cgo/test/issue4857.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#cgo CFLAGS: -Werror -const struct { int a; } *issue4857() { return (void *)0; } -*/ -import "C" - -func test4857() { - _ = C.issue4857() -} diff --git a/libgo/misc/cgo/test/issue5227.go b/libgo/misc/cgo/test/issue5227.go deleted file mode 100644 index 53c3bf1..0000000 --- a/libgo/misc/cgo/test/issue5227.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 5227: linker incorrectly treats common symbols and -// leaves them undefined. - -package cgotest - -/* -typedef struct { - int Count; -} Fontinfo; - -Fontinfo SansTypeface; - -extern void init(); - -Fontinfo loadfont() { - Fontinfo f = {0}; - return f; -} - -void init() { - SansTypeface = loadfont(); -} -*/ -import "C" - -import "testing" - -func test5227(t *testing.T) { - C.init() -} - -func selectfont() C.Fontinfo { - return C.SansTypeface -} diff --git a/libgo/misc/cgo/test/issue5242.go b/libgo/misc/cgo/test/issue5242.go deleted file mode 100644 index c81cd40..0000000 --- a/libgo/misc/cgo/test/issue5242.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 5242. Cgo incorrectly computed the alignment of structs -// with no Go accessible fields as 0, and then panicked on -// modulo-by-zero computations. - -package cgotest - -/* -typedef struct { -} foo; - -typedef struct { - int x : 1; -} bar; - -int issue5242(foo f, bar b) { - return 5242; -} -*/ -import "C" - -import "testing" - -func test5242(t *testing.T) { - if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 { - t.Errorf("got %v", got) - } -} diff --git a/libgo/misc/cgo/test/issue5337.go b/libgo/misc/cgo/test/issue5337.go deleted file mode 100644 index 9041d95..0000000 --- a/libgo/misc/cgo/test/issue5337.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !windows - -package cgotest - -/* -#include -#include - -static void *thread1(void *p) { - (void)p; - pthread_kill(pthread_self(), SIGPROF); - return NULL; -} -void test5337() { - pthread_t tid; - pthread_create(&tid, 0, thread1, NULL); - pthread_join(tid, 0); -} -*/ -import "C" - -import "testing" - -// Verify that we can withstand SIGPROF received on foreign threads -func test5337(t *testing.T) { - C.test5337() -} diff --git a/libgo/misc/cgo/test/issue5337w.go b/libgo/misc/cgo/test/issue5337w.go deleted file mode 100644 index 7b46757..0000000 --- a/libgo/misc/cgo/test/issue5337w.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows - -package cgotest - -import "testing" - -func test5337(t *testing.T) {} diff --git a/libgo/misc/cgo/test/issue5548.go b/libgo/misc/cgo/test/issue5548.go deleted file mode 100644 index 0710da7..0000000 --- a/libgo/misc/cgo/test/issue5548.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import "testing" - -/* -extern int issue5548_in_c(void); -*/ -import "C" - -//export issue5548FromC -func issue5548FromC(s string, i int) int { - if len(s) == 4 && s == "test" && i == 42 { - return 12345 - } - println("got", len(s), i) - return 9876 -} - -func test5548(t *testing.T) { - if x := C.issue5548_in_c(); x != 12345 { - t.Errorf("issue5548_in_c = %d, want %d", x, 12345) - } -} diff --git a/libgo/misc/cgo/test/issue5603.go b/libgo/misc/cgo/test/issue5603.go deleted file mode 100644 index ab84339..0000000 --- a/libgo/misc/cgo/test/issue5603.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -const long long issue5603exp = 0x12345678; -long long issue5603foo0() { return issue5603exp; } -long long issue5603foo1(void *p) { return issue5603exp; } -long long issue5603foo2(void *p, void *q) { return issue5603exp; } -long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; } -long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; } -*/ -import "C" - -import "testing" - -func test5603(t *testing.T) { - var x [5]int64 - exp := int64(C.issue5603exp) - x[0] = int64(C.issue5603foo0()) - x[1] = int64(C.issue5603foo1(nil)) - x[2] = int64(C.issue5603foo2(nil, nil)) - x[3] = int64(C.issue5603foo3(nil, nil, nil)) - x[4] = int64(C.issue5603foo4(nil, nil, nil, nil)) - for i, v := range x { - if v != exp { - t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp) - } - } -} diff --git a/libgo/misc/cgo/test/issue5740.go b/libgo/misc/cgo/test/issue5740.go deleted file mode 100644 index 059e316..0000000 --- a/libgo/misc/cgo/test/issue5740.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// int test5740a(void), test5740b(void); -import "C" -import "testing" - -func test5740(t *testing.T) { - if v := C.test5740a() + C.test5740b(); v != 5 { - t.Errorf("expected 5, got %v", v) - } -} diff --git a/libgo/misc/cgo/test/issue5986.go b/libgo/misc/cgo/test/issue5986.go deleted file mode 100644 index 9be1614..0000000 --- a/libgo/misc/cgo/test/issue5986.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#cgo LDFLAGS: -lm -#include -#include - -static void output5986() -{ - int current_row = 0, row_count = 0; - double sum_squares = 0; - double d; - do { - if (current_row == 10) { - current_row = 0; - } - ++row_count; - } - while (current_row++ != 1); - d = sqrt(sum_squares / row_count); - printf("sqrt is: %g\n", d); -} -*/ -import "C" -import "testing" - -func test5986(t *testing.T) { - C.output5986() -} diff --git a/libgo/misc/cgo/test/issue6128.go b/libgo/misc/cgo/test/issue6128.go deleted file mode 100644 index 9832d79..0000000 --- a/libgo/misc/cgo/test/issue6128.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Test handling of #defined names in clang. -// golang.org/issue/6128. - -/* -// NOTE: Must use hex, or else a shortcut for decimals -// in cgo avoids trying to pass this to clang. -#define X 0x1 -*/ -import "C" - -func test6128() { - // nothing to run, just make sure this compiles. - _ = C.X -} diff --git a/libgo/misc/cgo/test/issue6390.go b/libgo/misc/cgo/test/issue6390.go deleted file mode 100644 index 5642899..0000000 --- a/libgo/misc/cgo/test/issue6390.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// #include -import "C" - -import "testing" - -func test6390(t *testing.T) { - p1 := C.malloc(1024) - if p1 == nil { - t.Fatalf("C.malloc(1024) returned nil") - } - p2 := C.malloc(0) - if p2 == nil { - t.Fatalf("C.malloc(0) returned nil") - } - C.free(p1) - C.free(p2) -} diff --git a/libgo/misc/cgo/test/issue6472.go b/libgo/misc/cgo/test/issue6472.go deleted file mode 100644 index d416a05..0000000 --- a/libgo/misc/cgo/test/issue6472.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -typedef struct -{ - struct - { - int x; - } y[16]; -} z; -*/ -import "C" - -func test6472() { - // nothing to run, just make sure this compiles - s := new(C.z) - println(s.y[0].x) -} diff --git a/libgo/misc/cgo/test/issue6506.go b/libgo/misc/cgo/test/issue6506.go deleted file mode 100644 index c54b54b..0000000 --- a/libgo/misc/cgo/test/issue6506.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -// Test handling of size_t in the face of incorrect clang debug information. -// golang.org/issue/6506. - -/* -#include -#include -*/ -import "C" - -func test6506() { - // nothing to run, just make sure this compiles - var x C.size_t - - C.calloc(x, x) - C.malloc(x) - C.realloc(nil, x) - C.memcpy(nil, nil, x) - C.memcmp(nil, nil, x) - C.memmove(nil, nil, x) - C.strncpy(nil, nil, x) - C.strncmp(nil, nil, x) - C.strncat(nil, nil, x) - x = C.strxfrm(nil, nil, x) - C.memchr(nil, 0, x) - x = C.strcspn(nil, nil) - x = C.strspn(nil, nil) - C.memset(nil, 0, x) - x = C.strlen(nil) - _ = x -} diff --git a/libgo/misc/cgo/test/issue6612.go b/libgo/misc/cgo/test/issue6612.go deleted file mode 100644 index 15a12fa..0000000 --- a/libgo/misc/cgo/test/issue6612.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// golang.org/issue/6612 -// Test new scheme for deciding whether C.name is an expression, type, constant. -// Clang silences some warnings when the name is a #defined macro, so test those too -// (even though we now use errors exclusively, not warnings). - -package cgotest - -/* -void myfunc(void) {} -int myvar = 5; -const char *mytext = "abcdef"; -typedef int mytype; -enum { - myenum = 1234, -}; - -#define myfunc_def myfunc -#define myvar_def myvar -#define mytext_def mytext -#define mytype_def mytype -#define myenum_def myenum -#define myint_def 12345 -#define myfloat_def 1.5 -#define mystring_def "hello" -*/ -import "C" - -import "testing" - -func testNaming(t *testing.T) { - C.myfunc() - C.myfunc_def() - if v := C.myvar; v != 5 { - t.Errorf("C.myvar = %d, want 5", v) - } - if v := C.myvar_def; v != 5 { - t.Errorf("C.myvar_def = %d, want 5", v) - } - if s := C.GoString(C.mytext); s != "abcdef" { - t.Errorf("C.mytext = %q, want %q", s, "abcdef") - } - if s := C.GoString(C.mytext_def); s != "abcdef" { - t.Errorf("C.mytext_def = %q, want %q", s, "abcdef") - } - if c := C.myenum; c != 1234 { - t.Errorf("C.myenum = %v, want 1234", c) - } - if c := C.myenum_def; c != 1234 { - t.Errorf("C.myenum_def = %v, want 1234", c) - } - { - const c = C.myenum - if c != 1234 { - t.Errorf("C.myenum as const = %v, want 1234", c) - } - } - { - const c = C.myenum_def - if c != 1234 { - t.Errorf("C.myenum as const = %v, want 1234", c) - } - } - if c := C.myint_def; c != 12345 { - t.Errorf("C.myint_def = %v, want 12345", c) - } - { - const c = C.myint_def - if c != 12345 { - t.Errorf("C.myint as const = %v, want 12345", c) - } - } - - if c := C.myfloat_def; c != 1.5 { - t.Errorf("C.myint_def = %v, want 1.5", c) - } - { - const c = C.myfloat_def - if c != 1.5 { - t.Errorf("C.myint as const = %v, want 1.5", c) - } - } - - if s := C.mystring_def; s != "hello" { - t.Errorf("C.mystring_def = %q, want %q", s, "hello") - } -} diff --git a/libgo/misc/cgo/test/issue6833.go b/libgo/misc/cgo/test/issue6833.go deleted file mode 100644 index de60dbf..0000000 --- a/libgo/misc/cgo/test/issue6833.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -extern unsigned long long issue6833Func(unsigned int, unsigned long long); -*/ -import "C" - -import "testing" - -//export GoIssue6833Func -func GoIssue6833Func(aui uint, aui64 uint64) uint64 { - return aui64 + uint64(aui) -} - -func test6833(t *testing.T) { - ui := 7 - ull := uint64(0x4000300020001000) - v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull))) - exp := uint64(ui) + ull - if v != exp { - t.Errorf("issue6833Func() returns %x, expected %x", v, exp) - } -} diff --git a/libgo/misc/cgo/test/issue6907.go b/libgo/misc/cgo/test/issue6907.go deleted file mode 100644 index 00495ab..0000000 --- a/libgo/misc/cgo/test/issue6907.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include -#include - -char* Issue6907CopyString(_GoString_ s) { - size_t n; - const char *p; - char *r; - - n = _GoStringLen(s); - p = _GoStringPtr(s); - r = malloc(n + 1); - memmove(r, p, n); - r[n] = '\0'; - return r; -} -*/ -import "C" - -import "testing" - -func test6907(t *testing.T) { - want := "yarn" - if got := C.GoString(C.Issue6907CopyString(want)); got != want { - t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) - } -} diff --git a/libgo/misc/cgo/test/issue6907export.go b/libgo/misc/cgo/test/issue6907export.go deleted file mode 100644 index d41899e..0000000 --- a/libgo/misc/cgo/test/issue6907export.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -extern int CheckIssue6907C(_GoString_); -*/ -import "C" - -import ( - "testing" -) - -const CString = "C string" - -//export CheckIssue6907Go -func CheckIssue6907Go(s string) C.int { - if s == CString { - return 1 - } - return 0 -} - -func test6907Go(t *testing.T) { - if got := C.CheckIssue6907C(CString); got != 1 { - t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1) - } -} diff --git a/libgo/misc/cgo/test/issue7560.go b/libgo/misc/cgo/test/issue7560.go deleted file mode 100644 index f36d8a1..0000000 --- a/libgo/misc/cgo/test/issue7560.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -#include - -typedef struct { - char x; - long y; -} __attribute__((__packed__)) misaligned; - -int -offset7560(void) -{ - return (uintptr_t)&((misaligned*)0)->y; -} -*/ -import "C" - -import ( - "reflect" - "testing" -) - -func test7560(t *testing.T) { - // some mingw don't implement __packed__ correctly. - if C.offset7560() != 1 { - t.Skip("C compiler did not pack struct") - } - - // C.misaligned should have x but then a padding field to get to the end of the struct. - // There should not be a field named 'y'. - var v C.misaligned - rt := reflect.TypeOf(&v).Elem() - if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { - t.Errorf("unexpected fields in C.misaligned:\n") - for i := 0; i < rt.NumField(); i++ { - t.Logf("%+v\n", rt.Field(i)) - } - } -} diff --git a/libgo/misc/cgo/test/issue7665.go b/libgo/misc/cgo/test/issue7665.go deleted file mode 100644 index ce03458..0000000 --- a/libgo/misc/cgo/test/issue7665.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import ( - "testing" - "unsafe" -) - -// extern void f7665(void); -import "C" - -//export f7665 -func f7665() {} - -var bad7665 unsafe.Pointer = C.f7665 -var good7665 uintptr = uintptr(C.f7665) - -func test7665(t *testing.T) { - if bad7665 == nil || uintptr(bad7665) != good7665 { - t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665) - } -} diff --git a/libgo/misc/cgo/test/issue7786.go b/libgo/misc/cgo/test/issue7786.go deleted file mode 100644 index 1344e9e..0000000 --- a/libgo/misc/cgo/test/issue7786.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 7786. No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. - -package cgotest - -// struct test7786; -// typedef struct test7786 typedef_test7786; -// void f7786(struct test7786 *ctx) {} -// void g7786(typedef_test7786 *ctx) {} -// -// typedef struct body7786 typedef_body7786; -// struct body7786 { int x; }; -// void b7786(struct body7786 *ctx) {} -// void c7786(typedef_body7786 *ctx) {} -// -// typedef union union7786 typedef_union7786; -// void u7786(union union7786 *ctx) {} -// void v7786(typedef_union7786 *ctx) {} -import "C" - -func f() { - var x1 *C.typedef_test7786 - var x2 *C.struct_test7786 - x1 = x2 - x2 = x1 - C.f7786(x1) - C.f7786(x2) - C.g7786(x1) - C.g7786(x2) - - var b1 *C.typedef_body7786 - var b2 *C.struct_body7786 - b1 = b2 - b2 = b1 - C.b7786(b1) - C.b7786(b2) - C.c7786(b1) - C.c7786(b2) - - var u1 *C.typedef_union7786 - var u2 *C.union_union7786 - u1 = u2 - u2 = u1 - C.u7786(u1) - C.u7786(u2) - C.v7786(u1) - C.v7786(u2) -} diff --git a/libgo/misc/cgo/test/issue7978.go b/libgo/misc/cgo/test/issue7978.go deleted file mode 100644 index f0809d3..0000000 --- a/libgo/misc/cgo/test/issue7978.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 7978. Stack tracing didn't work during cgo code after calling a Go -// callback. Make sure GC works and the stack trace is correct. - -package cgotest - -/* -#include - -void issue7978cb(void); - -// use ugly atomic variable sync since that doesn't require calling back into -// Go code or OS dependencies -static void issue7978c(uint32_t *sync) { - while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0) - ; - __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST); - while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2) - ; - issue7978cb(); - __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST); - while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6) - ; -} -*/ -import "C" - -import ( - "runtime" - "runtime/debug" - "strings" - "sync/atomic" - "testing" -) - -var issue7978sync uint32 - -func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) { - runtime.GC() - buf := make([]byte, 65536) - trace := string(buf[:runtime.Stack(buf, true)]) - for _, goroutine := range strings.Split(trace, "\n\n") { - if strings.Contains(goroutine, "test.issue7978go") { - trace := strings.Split(goroutine, "\n") - // look for the expected function in the stack - for i := 0; i < depth; i++ { - if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) { - t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine) - return - } - if strings.Contains(trace[1+2*i], wantFunc) { - return - } - } - t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine) - return - } - } - t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace) -} - -func issue7978wait(store uint32, wait uint32) { - if store != 0 { - atomic.StoreUint32(&issue7978sync, store) - } - for atomic.LoadUint32(&issue7978sync) != wait { - runtime.Gosched() - } -} - -//export issue7978cb -func issue7978cb() { - // Force a stack growth from the callback to put extra - // pressure on the runtime. See issue #17785. - growStack(64) - issue7978wait(3, 4) -} - -func growStack(n int) int { - var buf [128]int - if n == 0 { - return 0 - } - return buf[growStack(n-1)] -} - -func issue7978go() { - C.issue7978c((*C.uint32_t)(&issue7978sync)) - issue7978wait(7, 8) -} - -func test7978(t *testing.T) { - if runtime.Compiler == "gccgo" { - t.Skip("gccgo can not do stack traces of C code") - } - debug.SetTraceback("2") - issue7978sync = 0 - go issue7978go() - // test in c code, before callback - issue7978wait(0, 1) - issue7978check(t, "_Cfunc_issue7978c(", "", 1) - // test in go code, during callback - issue7978wait(2, 3) - issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3) - // test in c code, after callback - issue7978wait(4, 5) - issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1) - // test in go code, after return from cgo - issue7978wait(6, 7) - issue7978check(t, "test.issue7978go(", "", 3) - atomic.StoreUint32(&issue7978sync, 8) -} diff --git a/libgo/misc/cgo/test/issue8092.go b/libgo/misc/cgo/test/issue8092.go deleted file mode 100644 index 19123e7..0000000 --- a/libgo/misc/cgo/test/issue8092.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8092. Test that linker defined symbols (e.g., text, data) don't -// conflict with C symbols. - -package cgotest - -/* -char text[] = "text"; -char data[] = "data"; -char *ctext(void) { return text; } -char *cdata(void) { return data; } -*/ -import "C" - -import "testing" - -func test8092(t *testing.T) { - tests := []struct { - s string - a, b *C.char - }{ - {"text", &C.text[0], C.ctext()}, - {"data", &C.data[0], C.cdata()}, - } - for _, test := range tests { - if test.a != test.b { - t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b) - } - if got := C.GoString(test.a); got != test.s { - t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s) - } - } -} diff --git a/libgo/misc/cgo/test/issue8331a.go b/libgo/misc/cgo/test/issue8331a.go deleted file mode 100644 index 92e2579..0000000 --- a/libgo/misc/cgo/test/issue8331a.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8331. A typedef of an unnamed struct is the same struct when -// #include'd twice. No runtime test; just make sure it compiles. - -package cgotest - -// #include "issue8331.h" -import "C" - -func issue8331a() C.issue8331 { - return issue8331Var -} diff --git a/libgo/misc/cgo/test/issue8331b.go b/libgo/misc/cgo/test/issue8331b.go deleted file mode 100644 index 5324aa2..0000000 --- a/libgo/misc/cgo/test/issue8331b.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8331. A typedef of an unnamed struct is the same struct when -// #include'd twice. No runtime test; just make sure it compiles. - -package cgotest - -// #include "issue8331.h" -import "C" - -var issue8331Var C.issue8331 diff --git a/libgo/misc/cgo/test/issue8428.go b/libgo/misc/cgo/test/issue8428.go deleted file mode 100644 index 2e5a555..0000000 --- a/libgo/misc/cgo/test/issue8428.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This test fails on older versions of OS X because they use older buggy -// versions of Clang that emit ambiguous DWARF info. See issue 8611. -// +build !darwin - -package cgotest - -// Issue 8428. Cgo inconsistently translated zero size arrays. - -/* -struct issue8428one { - char b; - char rest[]; -}; - -struct issue8428two { - void *p; - char b; - char rest[0]; - char pad; -}; - -struct issue8428three { - char w[1][2][3][0]; - char x[2][3][0][1]; - char y[3][0][1][2]; - char z[0][1][2][3]; -}; -*/ -import "C" - -import "unsafe" - -var _ = C.struct_issue8428one{ - b: C.char(0), - // The trailing rest field is not available in cgo. - // See issue 11925. - // rest: [0]C.char{}, -} - -var _ = C.struct_issue8428two{ - p: unsafe.Pointer(nil), - b: C.char(0), - rest: [0]C.char{}, -} - -var _ = C.struct_issue8428three{ - w: [1][2][3][0]C.char{}, - x: [2][3][0][1]C.char{}, - y: [3][0][1][2]C.char{}, - z: [0][1][2][3]C.char{}, -} diff --git a/libgo/misc/cgo/test/issue8441.go b/libgo/misc/cgo/test/issue8441.go deleted file mode 100644 index 4489ca9..0000000 --- a/libgo/misc/cgo/test/issue8441.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8368 and 8441. Recursive struct definitions didn't work. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -typedef struct one one; -typedef struct two two; -struct one { - two *x; -}; -struct two { - one *x; -}; -*/ -import "C" - -func issue8368(one *C.struct_one, two *C.struct_two) { -} - -func issue8441(one *C.one, two *C.two) { - issue8441(two.x, one.x) -} diff --git a/libgo/misc/cgo/test/issue8756.go b/libgo/misc/cgo/test/issue8756.go deleted file mode 100644 index d8ee3b8..0000000 --- a/libgo/misc/cgo/test/issue8756.go +++ /dev/null @@ -1,17 +0,0 @@ -package cgotest - -/* -#cgo LDFLAGS: -lm -#include -*/ -import "C" -import ( - "testing" - - "./issue8756" -) - -func test8756(t *testing.T) { - issue8756.Pow() - C.pow(1, 2) -} diff --git a/libgo/misc/cgo/test/issue8756/issue8756.go b/libgo/misc/cgo/test/issue8756/issue8756.go deleted file mode 100644 index 5f6b777..0000000 --- a/libgo/misc/cgo/test/issue8756/issue8756.go +++ /dev/null @@ -1,11 +0,0 @@ -package issue8756 - -/* -#cgo LDFLAGS: -lm -#include -*/ -import "C" - -func Pow() { - C.pow(1, 2) -} diff --git a/libgo/misc/cgo/test/issue8811.go b/libgo/misc/cgo/test/issue8811.go deleted file mode 100644 index f812732..0000000 --- a/libgo/misc/cgo/test/issue8811.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -/* -extern int issue8811Initialized; -extern void issue8811Init(); - -void issue8811Execute() { - if(!issue8811Initialized) - issue8811Init(); -} -*/ -import "C" - -import "testing" - -func test8811(t *testing.T) { - C.issue8811Execute() -} diff --git a/libgo/misc/cgo/test/issue8828.go b/libgo/misc/cgo/test/issue8828.go deleted file mode 100644 index 304797c..0000000 --- a/libgo/misc/cgo/test/issue8828.go +++ /dev/null @@ -1,16 +0,0 @@ -// compile - -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Issue 8828: compiling a file with -compiler=gccgo fails if a .c file -// has the same name as compiled directory. - -package cgotest - -import "./issue8828" - -func p() { - issue8828.Bar() -} diff --git a/libgo/misc/cgo/test/issue8828/issue8828.c b/libgo/misc/cgo/test/issue8828/issue8828.c deleted file mode 100644 index 27ec23a..0000000 --- a/libgo/misc/cgo/test/issue8828/issue8828.c +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -void foo() -{ -} diff --git a/libgo/misc/cgo/test/issue8828/trivial.go b/libgo/misc/cgo/test/issue8828/trivial.go deleted file mode 100644 index e7b9a4e..0000000 --- a/libgo/misc/cgo/test/issue8828/trivial.go +++ /dev/null @@ -1,8 +0,0 @@ -package issue8828 - -//void foo(); -import "C" - -func Bar() { - C.foo() -} diff --git a/libgo/misc/cgo/test/issue9026.go b/libgo/misc/cgo/test/issue9026.go deleted file mode 100644 index 8848d0e..0000000 --- a/libgo/misc/cgo/test/issue9026.go +++ /dev/null @@ -1,9 +0,0 @@ -package cgotest - -import ( - "testing" - - "./issue9026" -) - -func test9026(t *testing.T) { issue9026.Test(t) } diff --git a/libgo/misc/cgo/test/issue9026/issue9026.go b/libgo/misc/cgo/test/issue9026/issue9026.go deleted file mode 100644 index 149c265..0000000 --- a/libgo/misc/cgo/test/issue9026/issue9026.go +++ /dev/null @@ -1,36 +0,0 @@ -package issue9026 - -// This file appears in its own package since the assertion tests the -// per-package counter used to create fresh identifiers. - -/* -typedef struct {} git_merge_file_input; - -typedef struct {} git_merge_file_options; - -void git_merge_file( - git_merge_file_input *in, - git_merge_file_options *opts) {} -*/ -import "C" -import ( - "fmt" - "testing" -) - -func Test(t *testing.T) { - var in C.git_merge_file_input - var opts *C.git_merge_file_options - C.git_merge_file(&in, opts) - - // Test that the generated type names are deterministic. - // (Previously this would fail about 10% of the time.) - // - // Brittle: the assertion may fail spuriously when the algorithm - // changes, but should remain stable otherwise. - got := fmt.Sprintf("%T %T", in, opts) - want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0" - if got != want { - t.Errorf("Non-deterministic type names: got %s, want %s", got, want) - } -} diff --git a/libgo/misc/cgo/test/issue9400/asm_386.s b/libgo/misc/cgo/test/issue9400/asm_386.s deleted file mode 100644 index 7f158b5..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_386.s +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 - MOVL $·Baton(SB), BX - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADDL $(1024 * 8), SP - - // Ask signaller to setgid - MOVL $1, (BX) - - // Wait for setgid completion -loop: - PAUSE - MOVL (BX), AX - CMPL AX, $0 - JNE loop - - // Restore stack - SUBL $(1024 * 8), SP - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_amd64x.s b/libgo/misc/cgo/test/issue9400/asm_amd64x.s deleted file mode 100644 index 48b8619..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_amd64x.s +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build amd64 amd64p32 -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADDQ $(1024 * 8), SP - - // Ask signaller to setgid - MOVL $1, ·Baton(SB) - - // Wait for setgid completion -loop: - PAUSE - MOVL ·Baton(SB), AX - CMPL AX, $0 - JNE loop - - // Restore stack - SUBQ $(1024 * 8), SP - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_arm.s b/libgo/misc/cgo/test/issue9400/asm_arm.s deleted file mode 100644 index 96c2785..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_arm.s +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -#include "textflag.h" - -TEXT cas<>(SB),NOSPLIT,$0 - MOVW $0xffff0fc0, R15 // R15 is PC - -TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 - // Save link register - MOVW R14, R4 - - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADD $(1024 * 8), R13 - - // Ask signaller to setgid - MOVW $·Baton(SB), R2 -storeloop: - MOVW 0(R2), R0 - MOVW $1, R1 - BL cas<>(SB) - BCC storeloop - - // Wait for setgid completion -loop: - MOVW $0, R0 - MOVW $0, R1 - BL cas<>(SB) - BCC loop - - // Restore stack - SUB $(1024 * 8), R13 - - MOVW R4, R14 - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_arm64.s b/libgo/misc/cgo/test/issue9400/asm_arm64.s deleted file mode 100644 index 2ebbfcc..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_arm64.s +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 - // Save link register - MOVD R30, R9 - - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADD $(1024 * 8), RSP - - // Ask signaller to setgid - MOVD $·Baton(SB), R0 - MOVD $1, R1 -storeloop: - LDAXRW (R0), R2 - STLXRW R1, (R0), R3 - CBNZ R3, storeloop - - // Wait for setgid completion - MOVW $0, R1 - MOVW $0, R2 -loop: - LDAXRW (R0), R3 - CMPW R1, R3 - BNE loop - STLXRW R2, (R0), R3 - CBNZ R3, loop - - // Restore stack - SUB $(1024 * 8), RSP - - MOVD R9, R30 - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_mips64x.s b/libgo/misc/cgo/test/issue9400/asm_mips64x.s deleted file mode 100644 index 63dc906..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_mips64x.s +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build mips64 mips64le -// +build !gccgo - -#include "textflag.h" - -#define SYNC WORD $0xf - -TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADDV $(1024*8), R29 - - // Ask signaller to setgid - MOVW $1, R1 - SYNC - MOVW R1, ·Baton(SB) - SYNC - - // Wait for setgid completion -loop: - SYNC - MOVW ·Baton(SB), R1 - OR R2, R2, R2 // hint that we're in a spin loop - BNE R1, loop - SYNC - - // Restore stack - ADDV $(-1024*8), R29 - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_mipsx.s b/libgo/misc/cgo/test/issue9400/asm_mipsx.s deleted file mode 100644 index 7a92735..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_mipsx.s +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build mips mipsle -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADDU $(1024*8), R29 - - // Ask signaller to setgid - MOVW $1, R1 - SYNC - MOVW R1, ·Baton(SB) - SYNC - - // Wait for setgid completion -loop: - SYNC - MOVW ·Baton(SB), R1 - OR R2, R2, R2 // hint that we're in a spin loop - BNE R1, loop - SYNC - - // Restore stack - ADDU $(-1024*8), R29 - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_ppc64x.s b/libgo/misc/cgo/test/issue9400/asm_ppc64x.s deleted file mode 100644 index c88ec3b..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_ppc64x.s +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ppc64 ppc64le -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADD $(1024 * 8), R1 - - // Ask signaller to setgid - MOVW $1, R3 - SYNC - MOVW R3, ·Baton(SB) - - // Wait for setgid completion -loop: - SYNC - MOVW ·Baton(SB), R3 - CMP R3, $0 - // Hint that we're in a spin loop - OR R1, R1, R1 - BNE loop - ISYNC - - // Restore stack - SUB $(1024 * 8), R1 - RET diff --git a/libgo/misc/cgo/test/issue9400/asm_s390x.s b/libgo/misc/cgo/test/issue9400/asm_s390x.s deleted file mode 100644 index fc9ad72..0000000 --- a/libgo/misc/cgo/test/issue9400/asm_s390x.s +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -#include "textflag.h" - -TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 - // Rewind stack pointer so anything that happens on the stack - // will clobber the test pattern created by the caller - ADD $(1024 * 8), R15 - - // Ask signaller to setgid - MOVD $·Baton(SB), R5 - MOVW $1, 0(R5) - - // Wait for setgid completion -loop: - SYNC - MOVW ·Baton(SB), R3 - CMPBNE R3, $0, loop - - // Restore stack - SUB $(1024 * 8), R15 - RET diff --git a/libgo/misc/cgo/test/issue9400/gccgo.go b/libgo/misc/cgo/test/issue9400/gccgo.go deleted file mode 100644 index a9b62b0..0000000 --- a/libgo/misc/cgo/test/issue9400/gccgo.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gccgo - -package issue9400 - -import ( - "runtime" - "sync/atomic" -) - -// The test for the gc compiler resets the stack pointer so that the -// stack gets modified. We don't have a way to do that for gccgo -// without writing more assembly code, which we haven't bothered to -// do. So this is not much of a test. - -var Baton int32 - -func RewindAndSetgid() { - atomic.StoreInt32(&Baton, 1) - for atomic.LoadInt32(&Baton) != 0 { - runtime.Gosched() - } -} diff --git a/libgo/misc/cgo/test/issue9400/stubs.go b/libgo/misc/cgo/test/issue9400/stubs.go deleted file mode 100644 index e431c5a..0000000 --- a/libgo/misc/cgo/test/issue9400/stubs.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -package issue9400 - -var Baton int32 - -func RewindAndSetgid() diff --git a/libgo/misc/cgo/test/issue9400_linux.go b/libgo/misc/cgo/test/issue9400_linux.go deleted file mode 100644 index 7719535..0000000 --- a/libgo/misc/cgo/test/issue9400_linux.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that SIGSETXID runs on signal stack, since it's likely to -// overflow if it runs on the Go stack. - -package cgotest - -/* -#include -#include -*/ -import "C" - -import ( - "runtime" - "sync/atomic" - "testing" - - "./issue9400" -) - -func test9400(t *testing.T) { - // We synchronize through a shared variable, so we need two procs - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) - - // Start signaller - atomic.StoreInt32(&issue9400.Baton, 0) - go func() { - // Wait for RewindAndSetgid - for atomic.LoadInt32(&issue9400.Baton) == 0 { - runtime.Gosched() - } - // Broadcast SIGSETXID - runtime.LockOSThread() - C.setgid(0) - // Indicate that signalling is done - atomic.StoreInt32(&issue9400.Baton, 0) - }() - - // Grow the stack and put down a test pattern - const pattern = 0x123456789abcdef - var big [1024]uint64 // len must match assembly - for i := range big { - big[i] = pattern - } - - // Temporarily rewind the stack and trigger SIGSETXID - issue9400.RewindAndSetgid() - - // Check test pattern - for i := range big { - if big[i] != pattern { - t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern)) - } - } -} diff --git a/libgo/misc/cgo/test/issue9510.go b/libgo/misc/cgo/test/issue9510.go deleted file mode 100644 index efd3f77..0000000 --- a/libgo/misc/cgo/test/issue9510.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that we can link together two different cgo packages that both -// use the same libgcc function. - -package cgotest - -import ( - "runtime" - "testing" - - "./issue9510a" - "./issue9510b" -) - -func test9510(t *testing.T) { - if runtime.GOARCH == "arm" { - t.Skip("skipping because libgcc may be a Thumb library") - } - issue9510a.F(1, 1) - issue9510b.F(1, 1) -} diff --git a/libgo/misc/cgo/test/issue9510a/a.go b/libgo/misc/cgo/test/issue9510a/a.go deleted file mode 100644 index 1a5224b..0000000 --- a/libgo/misc/cgo/test/issue9510a/a.go +++ /dev/null @@ -1,15 +0,0 @@ -package issue9510a - -/* -static double csquare(double a, double b) { - __complex__ double d; - __real__ d = a; - __imag__ d = b; - return __real__ (d * d); -} -*/ -import "C" - -func F(a, b float64) float64 { - return float64(C.csquare(C.double(a), C.double(b))) -} diff --git a/libgo/misc/cgo/test/issue9510b/b.go b/libgo/misc/cgo/test/issue9510b/b.go deleted file mode 100644 index 5016b39..0000000 --- a/libgo/misc/cgo/test/issue9510b/b.go +++ /dev/null @@ -1,15 +0,0 @@ -package issue9510b - -/* -static double csquare(double a, double b) { - __complex__ double d; - __real__ d = a; - __imag__ d = b; - return __real__ (d * d); -} -*/ -import "C" - -func F(a, b float64) float64 { - return float64(C.csquare(C.double(a), C.double(b))) -} diff --git a/libgo/misc/cgo/test/issue9557.go b/libgo/misc/cgo/test/issue9557.go deleted file mode 100644 index 4e8922a..0000000 --- a/libgo/misc/cgo/test/issue9557.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// cgo rewrote C.var to *_Cvar_var, but left -// C.var.field as _Cvar.var.field. It now rewrites -// the latter as (*_Cvar_var).field. -// See https://golang.org/issue/9557. - -package cgotest - -// struct issue9557_t { -// int a; -// } test9557bar = { 42 }; -// -// struct issue9557_t *issue9557foo = &test9557bar; -import "C" -import "testing" - -func test9557(t *testing.T) { - // implicitly dereference a Go variable - foo := C.issue9557foo - if v := foo.a; v != 42 { - t.Fatalf("foo.a expected 42, but got %d", v) - } - - // explicitly dereference a C variable - if v := (*C.issue9557foo).a; v != 42 { - t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v) - } - - // implicitly dereference a C variable - if v := C.issue9557foo.a; v != 42 { - t.Fatalf("C.issue9557foo.a expected 42, but is %d", v) - } -} diff --git a/libgo/misc/cgo/test/overlaydir_test.go b/libgo/misc/cgo/test/overlaydir_test.go new file mode 100644 index 0000000..1b5c67d --- /dev/null +++ b/libgo/misc/cgo/test/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/test/pkg_test.go b/libgo/misc/cgo/test/pkg_test.go new file mode 100644 index 0000000..08e075c --- /dev/null +++ b/libgo/misc/cgo/test/pkg_test.go @@ -0,0 +1,69 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import ( + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +// TestCrossPackageTests compiles and runs tests that depend on imports of other +// local packages, using source code stored in the testdata directory. +// +// The tests in the misc directory tree do not have a valid import path in +// GOPATH mode, so they previously used relative imports. However, relative +// imports do not work in module mode. In order to make the test work in both +// modes, we synthesize a GOPATH in which the module paths are equivalent, and +// run the tests as a subprocess. +// +// If and when we no longer support these tests in GOPATH mode, we can remove +// this shim and move the tests currently located in testdata back into the +// parent directory. +func TestCrossPackageTests(t *testing.T) { + switch runtime.GOOS { + case "android": + t.Skip("Can't exec cmd/go subprocess on Android.") + case "darwin": + switch runtime.GOARCH { + case "arm", "arm64": + t.Skip("Can't exec cmd/go subprocess on iOS.") + } + } + + GOPATH, err := ioutil.TempDir("", "cgotest") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(GOPATH) + + modRoot := filepath.Join(GOPATH, "src", "cgotest") + if err := overlayDir(modRoot, "testdata"); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgotest\n"), 0666); err != nil { + t.Fatal(err) + } + + cmd := exec.Command("go", "test") + if testing.Verbose() { + cmd.Args = append(cmd.Args, "-v") + } + if testing.Short() { + cmd.Args = append(cmd.Args, "-short") + } + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH, "PWD="+cmd.Dir) + out, err := cmd.CombinedOutput() + if err == nil { + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + } else { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } +} diff --git a/libgo/misc/cgo/test/sigaltstack.go b/libgo/misc/cgo/test/sigaltstack.go index 2b7a1ec..2c9b81c 100644 --- a/libgo/misc/cgo/test/sigaltstack.go +++ b/libgo/misc/cgo/test/sigaltstack.go @@ -55,7 +55,7 @@ import ( func testSigaltstack(t *testing.T) { switch { - case runtime.GOOS == "solaris", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"): + case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"): t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) case runtime.GOOS == "darwin" && runtime.GOARCH == "386": t.Skipf("sigaltstack fails on darwin/386") diff --git a/libgo/misc/cgo/test/test.go b/libgo/misc/cgo/test/test.go new file mode 100644 index 0000000..2d060bf --- /dev/null +++ b/libgo/misc/cgo/test/test.go @@ -0,0 +1,2104 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test cases for cgo. +// Both the import "C" prologue and the main file are sorted by issue number. +// This file contains C definitions (not just declarations) +// and so it must NOT contain any //export directives on Go functions. +// See testx.go for exports. + +package cgotest + +/* +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#cgo LDFLAGS: -lm + +#ifndef WIN32 +#include +#include +#endif + +// alignment tests + +typedef unsigned char Uint8; +typedef unsigned short Uint16; + +typedef enum { + MOD1 = 0x0000, + MODX = 0x8000 +} SDLMod; + +typedef enum { + A1 = 1, + B1 = 322, + SDLK_LAST +} SDLKey; + +typedef struct SDL_keysym { + Uint8 scancode; + SDLKey sym; + SDLMod mod; + Uint16 unicode; +} SDL_keysym; + +typedef struct SDL_KeyboardEvent { + Uint8 typ; + Uint8 which; + Uint8 state; + SDL_keysym keysym; +} SDL_KeyboardEvent; + +void makeEvent(SDL_KeyboardEvent *event) { + unsigned char *p; + int i; + + p = (unsigned char*)event; + for (i=0; ityp == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni; +} + +void cTest(SDL_KeyboardEvent *event) { + printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, + event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); + fflush(stdout); +} + +// api + +const char *greeting = "hello, world"; + +// basic test cases + +#define SHIFT(x, y) ((x)<<(y)) +#define KILO SHIFT(1, 10) +#define UINT32VAL 0xc008427bU + +enum E { + Enum1 = 1, + Enum2 = 2, +}; + +typedef unsigned char cgo_uuid_t[20]; + +void uuid_generate(cgo_uuid_t x) { + x[0] = 0; +} + +struct S { + int x; +}; + +const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + +extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); + +enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } + +int add(int x, int y) { + return x+y; +}; + +// complex alignment + +struct { + float x; + _Complex float y; +} cplxAlign = { 3.14, 2.17 }; + +// constants and pointer checking + +#define CheckConstVal 0 + +typedef struct { + int *p; +} CheckConstStruct; + +static void CheckConstFunc(CheckConstStruct *p, int e) {} + +// duplicate symbol + +int base_symbol = 0; +#define alias_one base_symbol +#define alias_two base_symbol + +// function pointer variables + +typedef int (*intFunc) (); + +int +bridge_int_func(intFunc f) +{ + return f(); +} + +int fortytwo() +{ + return 42; +} + +// issue 1222 +typedef union { + long align; +} xxpthread_mutex_t; +struct ibv_async_event { + union { + int x; + } element; +}; +struct ibv_context { + xxpthread_mutex_t mutex; +}; + +// issue 1635 +// Mac OS X's gcc will generate scattered relocation 2/1 for +// this function on Darwin/386, and 8l couldn't handle it. +// this example is in issue 1635 +void scatter() { + void *p = scatter; + printf("scatter = %p\n", p); +} + +// Adding this explicit extern declaration makes this a test for +// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 . +// It used to cause a cgo error when building with GCC 6. +extern int hola; + +// this example is in issue 3253 +int hola = 0; +int testHola() { return hola; } + +// issue 3250 +#ifdef WIN32 +void testSendSIG() {} +#else +static void *thread(void *p) { + const int M = 100; + int i; + (void)p; + for (i = 0; i < M; i++) { + pthread_kill(pthread_self(), SIGCHLD); + usleep(rand() % 20 + 5); + } + return NULL; +} +void testSendSIG() { + const int N = 20; + int i; + pthread_t tid[N]; + for (i = 0; i < N; i++) { + usleep(rand() % 200 + 100); + pthread_create(&tid[i], 0, thread, NULL); + } + for (i = 0; i < N; i++) + pthread_join(tid[i], 0); +} +#endif + +// issue 3261 +// libgcc on ARM might be compiled as thumb code, but our 5l +// can't handle that, so we have to disable this test on arm. +#ifdef __ARMEL__ +int vabs(int x) { + puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library."); + return (x < 0) ? -x : x; +} +#elif defined(__arm64__) && defined(__clang__) +int vabs(int x) { + puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc."); + return (x < 0) ? -x : x; +} +#else +int __absvsi2(int); // dummy prototype for libgcc function +// we shouldn't name the function abs, as gcc might use +// the builtin one. +int vabs(int x) { return __absvsi2(x); } +#endif + + +// issue 3729 +// access errno from void C function +const char _expA = 0x42; +const float _expB = 3.14159; +const short _expC = 0x55aa; +const int _expD = 0xdeadbeef; + +#ifdef WIN32 +void g(void) {} +void g2(int x, char a, float b, short c, int d) {} +#else + +void g(void) { + errno = E2BIG; +} + +// try to pass some non-trivial arguments to function g2 +void g2(int x, char a, float b, short c, int d) { + if (a == _expA && b == _expB && c == _expC && d == _expD) + errno = x; + else + errno = -1; +} +#endif + +// issue 3945 +// Test that cgo reserves enough stack space during cgo call. +// See https://golang.org/issue/3945 for details. +void say() { + printf("%s from C\n", "hello"); +} + +// issue 4054 part 1 - other half in testx.go + +typedef enum { + A = 0, + B, + C, + D, + E, + F, + G, + H, + II, + J, +} issue4054a; + +// issue 4339 +// We've historically permitted #include <>, so test it here. Issue 29333. +#include + +// issue 4417 +// cmd/cgo: bool alignment/padding issue. +// bool alignment is wrong and causing wrong arguments when calling functions. +static int c_bool(bool a, bool b, int c, bool d, bool e) { + return c; +} + +// issue 4857 +#cgo CFLAGS: -Werror +const struct { int a; } *issue4857() { return (void *)0; } + +// issue 5224 +// Test that the #cgo CFLAGS directive works, +// with and without platform filters. +#cgo CFLAGS: -DCOMMON_VALUE=123 +#cgo windows CFLAGS: -DIS_WINDOWS=1 +#cgo !windows CFLAGS: -DIS_WINDOWS=0 +int common = COMMON_VALUE; +int is_windows = IS_WINDOWS; + +// issue 5227 +// linker incorrectly treats common symbols and +// leaves them undefined. + +typedef struct { + int Count; +} Fontinfo; + +Fontinfo SansTypeface; + +extern void init(); + +Fontinfo loadfont() { + Fontinfo f = {0}; + return f; +} + +void init() { + SansTypeface = loadfont(); +} + +// issue 5242 +// Cgo incorrectly computed the alignment of structs +// with no Go accessible fields as 0, and then panicked on +// modulo-by-zero computations. +typedef struct { +} foo; + +typedef struct { + int x : 1; +} bar; + +int issue5242(foo f, bar b) { + return 5242; +} + +// issue 5337 +// Verify that we can withstand SIGPROF received on foreign threads + +#ifdef WIN32 +void test5337() {} +#else +static void *thread1(void *p) { + (void)p; + pthread_kill(pthread_self(), SIGPROF); + return NULL; +} +void test5337() { + pthread_t tid; + pthread_create(&tid, 0, thread1, NULL); + pthread_join(tid, 0); +} +#endif + +// issue 5603 + +const long long issue5603exp = 0x12345678; +long long issue5603foo0() { return issue5603exp; } +long long issue5603foo1(void *p) { return issue5603exp; } +long long issue5603foo2(void *p, void *q) { return issue5603exp; } +long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; } +long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; } + +// issue 5740 + +int test5740a(void), test5740b(void); + +// issue 5986 +static void output5986() +{ + int current_row = 0, row_count = 0; + double sum_squares = 0; + double d; + do { + if (current_row == 10) { + current_row = 0; + } + ++row_count; + } + while (current_row++ != 1); + d = sqrt(sum_squares / row_count); + printf("sqrt is: %g\n", d); +} + +// issue 6128 +// Test handling of #defined names in clang. +// NOTE: Must use hex, or else a shortcut for decimals +// in cgo avoids trying to pass this to clang. +#define X 0x1 + +// issue 6472 +typedef struct +{ + struct + { + int x; + } y[16]; +} z; + +// issue 6612 +// Test new scheme for deciding whether C.name is an expression, type, constant. +// Clang silences some warnings when the name is a #defined macro, so test those too +// (even though we now use errors exclusively, not warnings). + +void myfunc(void) {} +int myvar = 5; +const char *mytext = "abcdef"; +typedef int mytype; +enum { + myenum = 1234, +}; + +#define myfunc_def myfunc +#define myvar_def myvar +#define mytext_def mytext +#define mytype_def mytype +#define myenum_def myenum +#define myint_def 12345 +#define myfloat_def 1.5 +#define mystring_def "hello" + +// issue 6907 +char* Issue6907CopyString(_GoString_ s) { + size_t n; + const char *p; + char *r; + + n = _GoStringLen(s); + p = _GoStringPtr(s); + r = malloc(n + 1); + memmove(r, p, n); + r[n] = '\0'; + return r; +} + +// issue 7560 +typedef struct { + char x; + long y; +} __attribute__((__packed__)) misaligned; + +int +offset7560(void) +{ + return (uintptr_t)&((misaligned*)0)->y; +} + +// issue 7786 +// No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. + +struct test7786; +typedef struct test7786 typedef_test7786; +void f7786(struct test7786 *ctx) {} +void g7786(typedef_test7786 *ctx) {} + +typedef struct body7786 typedef_body7786; +struct body7786 { int x; }; +void b7786(struct body7786 *ctx) {} +void c7786(typedef_body7786 *ctx) {} + +typedef union union7786 typedef_union7786; +void u7786(union union7786 *ctx) {} +void v7786(typedef_union7786 *ctx) {} + +// issue 8092 +// Test that linker defined symbols (e.g., text, data) don't +// conflict with C symbols. +char text[] = "text"; +char data[] = "data"; +char *ctext(void) { return text; } +char *cdata(void) { return data; } + +// issue 8428 +// Cgo inconsistently translated zero size arrays. + +struct issue8428one { + char b; + char rest[]; +}; + +struct issue8428two { + void *p; + char b; + char rest[0]; + char pad; +}; + +struct issue8428three { + char w[1][2][3][0]; + char x[2][3][0][1]; + char y[3][0][1][2]; + char z[0][1][2][3]; +}; + +// issue 8331 part 1 - part 2 in testx.go +// A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. +#include "issue8331.h" + +// issue 8368 and 8441 +// Recursive struct definitions didn't work. +// No runtime test; just make sure it compiles. +typedef struct one one; +typedef struct two two; +struct one { + two *x; +}; +struct two { + one *x; +}; + +// issue 8811 + +extern int issue8811Initialized; +extern void issue8811Init(); + +void issue8811Execute() { + if(!issue8811Initialized) + issue8811Init(); +} + +// issue 9557 + +struct issue9557_t { + int a; +} test9557bar = { 42 }; +struct issue9557_t *issue9557foo = &test9557bar; + +// issue 10303 +// Pointers passed to C were not marked as escaping (bug in cgo). + +typedef int *intptr; + +void setintstar(int *x) { + *x = 1; +} + +void setintptr(intptr x) { + *x = 1; +} + +void setvoidptr(void *x) { + *(int*)x = 1; +} + +typedef struct Struct Struct; +struct Struct { + int *P; +}; + +void setstruct(Struct s) { + *s.P = 1; +} + +// issue 11925 +// Structs with zero-length trailing fields are now padded by the Go compiler. + +struct a11925 { + int i; + char a[0]; + char b[0]; +}; + +struct b11925 { + int i; + char a[0]; + char b[]; +}; + +// issue 12030 +void issue12030conv(char *buf, double x) { + sprintf(buf, "d=%g", x); +} + +// issue 14838 + +int check_cbytes(char *b, size_t l) { + int i; + for (i = 0; i < l; i++) { + if (b[i] != i) { + return 0; + } + } + return 1; +} + +// issue 17065 +// Test that C symbols larger than a page play nicely with the race detector. +int ii[65537]; + +// issue 17537 +// The void* cast introduced by cgo to avoid problems +// with const/volatile qualifiers breaks C preprocessor macros that +// emulate functions. + +typedef struct { + int i; +} S17537; + +int I17537(S17537 *p); + +#define I17537(p) ((p)->i) + +// Calling this function used to fail without the cast. +const int F17537(const char **p) { + return **p; +} + +// issue 17723 +// API compatibility checks + +typedef char *cstring_pointer; +static void cstring_pointer_fun(cstring_pointer dummy) { } +const char *api_hello = "hello!"; + +// Calling this function used to trigger an error from the C compiler +// (issue 18298). +void F18298(const void *const *p) { +} + +// Test that conversions between typedefs work as they used to. +typedef const void *T18298_1; +struct S18298 { int i; }; +typedef const struct S18298 *T18298_2; +void G18298(T18298_1 t) { +} + +// issue 18126 +// cgo check of void function returning errno. +void Issue18126C(void **p) {} + +// issue 18720 + +#define HELLO "hello" +#define WORLD "world" +#define HELLO_WORLD HELLO "\000" WORLD + +struct foo { char c; }; +#define SIZE_OF(x) sizeof(x) +#define SIZE_OF_FOO SIZE_OF(struct foo) +#define VAR1 VAR +#define VAR var +int var = 5; + +#define ADDR &var + +#define CALL fn() +int fn(void) { + return ++var; +} + +// issue 20129 + +int issue20129 = 0; +typedef void issue20129Void; +issue20129Void issue20129Foo() { + issue20129 = 1; +} +typedef issue20129Void issue20129Void2; +issue20129Void2 issue20129Bar() { + issue20129 = 2; +} + +// issue 20369 +#define XUINT64_MAX 18446744073709551615ULL + +// issue 21668 +// Fail to guess the kind of the constant "x". +// No runtime test; just make sure it compiles. +const int x21668 = 42; + +// issue 21708 +#define CAST_TO_INT64 (int64_t)(-1) + +// issue 21809 +// Compile C `typedef` to go type aliases. + +typedef long MySigned_t; +// tests alias-to-alias +typedef MySigned_t MySigned2_t; +long takes_long(long x) { return x * x; } +MySigned_t takes_typedef(MySigned_t x) { return x * x; } + +// issue 22906 + +// It's going to be hard to include a whole real JVM to test this. +// So we'll simulate a really easy JVM using just the parts we need. +// This is the relevant part of jni.h. + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +typedef jobject jweak; + +// Note: jvalue is already a non-pointer type due to it being a C union. + +// issue 22958 + +typedef struct { + unsigned long long f8 : 8; + unsigned long long f16 : 16; + unsigned long long f24 : 24; + unsigned long long f32 : 32; + unsigned long long f40 : 40; + unsigned long long f48 : 48; + unsigned long long f56 : 56; + unsigned long long f64 : 64; +} issue22958Type; + +// issue 23356 +int a(void) { return 5; }; +int r(void) { return 3; }; + +// issue 23720 +typedef int *issue23720A; +typedef const int *issue23720B; +void issue23720F(issue23720B a) {} + +// issue 24206 +#if defined(__linux__) && defined(__x86_64__) +#include +// Returns string with null byte at the last valid address +char* dangerousString1() { + int pageSize = 4096; + char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); + mprotect(data + pageSize,pageSize,PROT_NONE); + int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte + int i = start; + for (; i < pageSize; i++) { + data[i] = 'x'; + } + data[pageSize -1 ] = 0; + return data+start; +} + +char* dangerousString2() { + int pageSize = 4096; + char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); + mprotect(data + 2 * pageSize,pageSize,PROT_NONE); + int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte + int i = start; + for (; i < 2 * pageSize; i++) { + data[i] = 'x'; + } + data[2*pageSize -1 ] = 0; + return data+start; +} +#else +char *dangerousString1() { return NULL; } +char *dangerousString2() { return NULL; } +#endif + +// issue 26066 +const unsigned long long int issue26066 = (const unsigned long long) -1; + +// issue 26517 +// Introduce two pointer types which are distinct, but have the same +// base type. Make sure that both of those pointer types get resolved +// correctly. Before the fix for 26517 if one of these pointer types +// was resolved before the other one was processed, the second one +// would never be resolved. +// Before this issue was fixed this test failed on Windows, +// where va_list expands to a named char* type. +typedef va_list TypeOne; +typedef char *TypeTwo; + +// issue 28540 + +static void twoargs1(void *p, int n) {} +static void *twoargs2() { return 0; } +static int twoargs3(void * p) { return 0; } + +// issue 28545 +// Failed to add type conversion for negative constant. + +static void issue28545F(char **p, int n, complex double a) {} + +// issue 28772 part 1 - part 2 in testx.go +// Failed to add type conversion for Go constant set to C constant. +// No runtime test; just make sure it compiles. + +#define issue28772Constant 1 + +// issue 28896 +// cgo was incorrectly adding padding after a packed struct. +typedef struct { + void *f1; + uint32_t f2; +} __attribute__((__packed__)) innerPacked; + +typedef struct { + innerPacked g1; + uint64_t g2; +} outerPacked; + +typedef struct { + void *f1; + uint32_t f2; +} innerUnpacked; + +typedef struct { + innerUnpacked g1; + uint64_t g2; +} outerUnpacked; + +size_t offset(int x) { + switch (x) { + case 0: + return offsetof(innerPacked, f2); + case 1: + return offsetof(outerPacked, g2); + case 2: + return offsetof(innerUnpacked, f2); + case 3: + return offsetof(outerUnpacked, g2); + default: + abort(); + } +} + +// issue 29748 + +typedef struct { char **p; } S29748; +static int f29748(S29748 *p) { return 0; } + +// issue 29781 +// Error with newline inserted into constant expression. +// Compilation test only, nothing to run. + +static void issue29781F(char **p, int n) {} +#define ISSUE29781C 0 + +// issue 31093 +static uint16_t issue31093F(uint16_t v) { return v; } + +// issue 32579 +typedef struct S32579 { unsigned char data[1]; } S32579; +*/ +import "C" + +import ( + "context" + "fmt" + "math" + "math/rand" + "os" + "os/signal" + "reflect" + "runtime" + "sync" + "syscall" + "testing" + "time" + "unsafe" +) + +// alignment + +func testAlign(t *testing.T) { + var evt C.SDL_KeyboardEvent + C.makeEvent(&evt) + if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { + t.Error("*** bad alignment") + C.cTest(&evt) + t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", + evt.typ, evt.which, evt.state, evt.keysym.scancode, + evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) + t.Error(evt) + } +} + +// api + +const greeting = "hello, world" + +type testPair struct { + Name string + Got, Want interface{} +} + +var testPairs = []testPair{ + {"GoString", C.GoString(C.greeting), greeting}, + {"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]}, + {"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])}, +} + +func testHelpers(t *testing.T) { + for _, pair := range testPairs { + if !reflect.DeepEqual(pair.Got, pair.Want) { + t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want) + } + } +} + +// basic test cases + +const EINVAL = C.EINVAL /* test #define */ + +var KILO = C.KILO + +func uuidgen() { + var uuid C.cgo_uuid_t + C.uuid_generate(&uuid[0]) +} + +func Strtol(s string, base int) (int, error) { + p := C.CString(s) + n, err := C.strtol(p, nil, C.int(base)) + C.free(unsafe.Pointer(p)) + return int(n), err +} + +func Atol(s string) int { + p := C.CString(s) + n := C.atol(p) + C.free(unsafe.Pointer(p)) + return int(n) +} + +func testConst(t *testing.T) { + C.myConstFunc(nil, 0, nil) +} + +func testEnum(t *testing.T) { + if C.Enum1 != 1 || C.Enum2 != 2 { + t.Error("bad enum", C.Enum1, C.Enum2) + } +} + +func testAtol(t *testing.T) { + l := Atol("123") + if l != 123 { + t.Error("Atol 123: ", l) + } +} + +func testErrno(t *testing.T) { + p := C.CString("no-such-file") + m := C.CString("r") + f, err := C.fopen(p, m) + C.free(unsafe.Pointer(p)) + C.free(unsafe.Pointer(m)) + if err == nil { + C.fclose(f) + t.Fatalf("C.fopen: should fail") + } + if err != syscall.ENOENT { + t.Fatalf("C.fopen: unexpected error: %v", err) + } +} + +func testMultipleAssign(t *testing.T) { + p := C.CString("234") + n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) + if runtime.GOOS == "openbsd" { + // Bug in OpenBSD strtol(3) - base > 36 succeeds. + if (n != 0 && n != 239089) || m != 234 { + t.Fatal("Strtol x2: ", n, m) + } + } else if n != 0 || m != 234 { + t.Fatal("Strtol x2: ", n, m) + } + C.free(unsafe.Pointer(p)) +} + +var ( + cuint = (C.uint)(0) + culong C.ulong + cchar C.char +) + +type Context struct { + ctx *C.struct_ibv_context +} + +func benchCgoCall(b *testing.B) { + const x = C.int(2) + const y = C.int(3) + for i := 0; i < b.N; i++ { + C.add(x, y) + } +} + +var sinkString string + +func benchGoString(b *testing.B) { + for i := 0; i < b.N; i++ { + sinkString = C.GoString(C.cstr) + } + const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890" + if sinkString != want { + b.Fatalf("%q != %q", sinkString, want) + } +} + +// Static (build-time) test that syntax traversal visits all operands of s[i:j:k]. +func sliceOperands(array [2000]int) { + _ = array[C.KILO:C.KILO:C.KILO] // no type error +} + +// set in cgo_thread_lock.go init +var testThreadLockFunc = func(*testing.T) {} + +// complex alignment + +func TestComplexAlign(t *testing.T) { + if C.cplxAlign.x != 3.14 { + t.Errorf("got %v, expected 3.14", C.cplxAlign.x) + } + if C.cplxAlign.y != 2.17 { + t.Errorf("got %v, expected 2.17", C.cplxAlign.y) + } +} + +// constants and pointer checking + +func testCheckConst(t *testing.T) { + // The test is that this compiles successfully. + p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0)))) + defer C.free(p) + C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal) +} + +// duplicate symbol + +func duplicateSymbols() { + fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two) +} + +// environment + +// This is really an os package test but here for convenience. +func testSetEnv(t *testing.T) { + if runtime.GOOS == "windows" { + // Go uses SetEnvironmentVariable on windows. However, + // C runtime takes a *copy* at process startup of the + // OS environment, and stores it in environ/envp. + // It is this copy that getenv/putenv manipulate. + t.Logf("skipping test") + return + } + const key = "CGO_OS_TEST_KEY" + const val = "CGO_OS_TEST_VALUE" + os.Setenv(key, val) + keyc := C.CString(key) + defer C.free(unsafe.Pointer(keyc)) + v := C.getenv(keyc) + if uintptr(unsafe.Pointer(v)) == 0 { + t.Fatal("getenv returned NULL") + } + vs := C.GoString(v) + if vs != val { + t.Fatalf("getenv() = %q; want %q", vs, val) + } +} + +// function pointer variables + +func callBridge(f C.intFunc) int { + return int(C.bridge_int_func(f)) +} + +func callCBridge(f C.intFunc) C.int { + return C.bridge_int_func(f) +} + +func testFpVar(t *testing.T) { + const expected = 42 + f := C.intFunc(C.fortytwo) + res1 := C.bridge_int_func(f) + if r1 := int(res1); r1 != expected { + t.Errorf("got %d, want %d", r1, expected) + } + res2 := callCBridge(f) + if r2 := int(res2); r2 != expected { + t.Errorf("got %d, want %d", r2, expected) + } + r3 := callBridge(f) + if r3 != expected { + t.Errorf("got %d, want %d", r3, expected) + } +} + +// issue 1222 +type AsyncEvent struct { + event C.struct_ibv_async_event +} + +// issue 1635 + +func test1635(t *testing.T) { + C.scatter() + if v := C.hola; v != 0 { + t.Fatalf("C.hola is %d, should be 0", v) + } + if v := C.testHola(); v != 0 { + t.Fatalf("C.testHola() is %d, should be 0", v) + } +} + +// issue 2470 + +func testUnsignedInt(t *testing.T) { + a := (int64)(C.UINT32VAL) + b := (int64)(0xc008427b) + if a != b { + t.Errorf("Incorrect unsigned int - got %x, want %x", a, b) + } +} + +// issue 3250 + +func test3250(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("not applicable on windows") + } + + t.Skip("skipped, see golang.org/issue/5885") + var ( + thres = 1 + sig = syscall_dot_SIGCHLD + ) + type result struct { + n int + sig os.Signal + } + var ( + sigCh = make(chan os.Signal, 10) + waitStart = make(chan struct{}) + waitDone = make(chan result) + ) + + signal.Notify(sigCh, sig) + + go func() { + n := 0 + alarm := time.After(time.Second * 3) + for { + select { + case <-waitStart: + waitStart = nil + case v := <-sigCh: + n++ + if v != sig || n > thres { + waitDone <- result{n, v} + return + } + case <-alarm: + waitDone <- result{n, sig} + return + } + } + }() + + waitStart <- struct{}{} + C.testSendSIG() + r := <-waitDone + if r.sig != sig { + t.Fatalf("received signal %v, but want %v", r.sig, sig) + } + t.Logf("got %d signals\n", r.n) + if r.n <= thres { + t.Fatalf("expected more than %d", thres) + } +} + +// issue 3261 + +func testLibgcc(t *testing.T) { + var table = []struct { + in, out C.int + }{ + {0, 0}, + {1, 1}, + {-42, 42}, + {1000300, 1000300}, + {1 - 1<<31, 1<<31 - 1}, + } + for _, v := range table { + if o := C.vabs(v.in); o != v.out { + t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out) + return + } + } +} + +// issue 3729 + +func test3729(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skipping on windows") + } + + _, e := C.g() + if e != syscall.E2BIG { + t.Errorf("got %q, expect %q", e, syscall.E2BIG) + } + _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) + if e != syscall.EINVAL { + t.Errorf("got %q, expect %q", e, syscall.EINVAL) + } +} + +// issue 3945 + +func testPrintf(t *testing.T) { + C.say() +} + +// issue 4054 + +var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} + +// issue 4339 + +func test4339(t *testing.T) { + C.handle4339(&C.exported4339) +} + +// issue 4417 + +func testBoolAlign(t *testing.T) { + b := C.c_bool(true, true, 10, true, false) + if b != 10 { + t.Fatalf("found %d expected 10\n", b) + } + b = C.c_bool(true, true, 5, true, true) + if b != 5 { + t.Fatalf("found %d expected 5\n", b) + } + b = C.c_bool(true, true, 3, true, false) + if b != 3 { + t.Fatalf("found %d expected 3\n", b) + } + b = C.c_bool(false, false, 1, true, false) + if b != 1 { + t.Fatalf("found %d expected 1\n", b) + } + b = C.c_bool(false, true, 200, true, false) + if b != 200 { + t.Fatalf("found %d expected 200\n", b) + } +} + +// issue 4857 + +func test4857() { + _ = C.issue4857() +} + +// issue 5224 + +func testCflags(t *testing.T) { + is_windows := C.is_windows == 1 + if is_windows != (runtime.GOOS == "windows") { + t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) + } + if C.common != 123 { + t.Errorf("common: %v (expected 123)", C.common) + } +} + +// issue 5227 + +func test5227(t *testing.T) { + C.init() +} + +func selectfont() C.Fontinfo { + return C.SansTypeface +} + +// issue 5242 + +func test5242(t *testing.T) { + if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 { + t.Errorf("got %v", got) + } +} + +func test5603(t *testing.T) { + var x [5]int64 + exp := int64(C.issue5603exp) + x[0] = int64(C.issue5603foo0()) + x[1] = int64(C.issue5603foo1(nil)) + x[2] = int64(C.issue5603foo2(nil, nil)) + x[3] = int64(C.issue5603foo3(nil, nil, nil)) + x[4] = int64(C.issue5603foo4(nil, nil, nil, nil)) + for i, v := range x { + if v != exp { + t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp) + } + } +} + +// issue 5337 + +func test5337(t *testing.T) { + C.test5337() +} + +// issue 5740 + +func test5740(t *testing.T) { + if v := C.test5740a() + C.test5740b(); v != 5 { + t.Errorf("expected 5, got %v", v) + } +} + +// issue 5986 + +func test5986(t *testing.T) { + C.output5986() +} + +// issue 6128 + +func test6128() { + // nothing to run, just make sure this compiles. + _ = C.X +} + +// issue 6390 + +func test6390(t *testing.T) { + p1 := C.malloc(1024) + if p1 == nil { + t.Fatalf("C.malloc(1024) returned nil") + } + p2 := C.malloc(0) + if p2 == nil { + t.Fatalf("C.malloc(0) returned nil") + } + C.free(p1) + C.free(p2) +} + +func test6472() { + // nothing to run, just make sure this compiles + s := new(C.z) + println(s.y[0].x) +} + +// issue 6506 + +func test6506() { + // nothing to run, just make sure this compiles + var x C.size_t + + C.calloc(x, x) + C.malloc(x) + C.realloc(nil, x) + C.memcpy(nil, nil, x) + C.memcmp(nil, nil, x) + C.memmove(nil, nil, x) + C.strncpy(nil, nil, x) + C.strncmp(nil, nil, x) + C.strncat(nil, nil, x) + x = C.strxfrm(nil, nil, x) + C.memchr(nil, 0, x) + x = C.strcspn(nil, nil) + x = C.strspn(nil, nil) + C.memset(nil, 0, x) + x = C.strlen(nil) + _ = x +} + +// issue 6612 + +func testNaming(t *testing.T) { + C.myfunc() + C.myfunc_def() + if v := C.myvar; v != 5 { + t.Errorf("C.myvar = %d, want 5", v) + } + if v := C.myvar_def; v != 5 { + t.Errorf("C.myvar_def = %d, want 5", v) + } + if s := C.GoString(C.mytext); s != "abcdef" { + t.Errorf("C.mytext = %q, want %q", s, "abcdef") + } + if s := C.GoString(C.mytext_def); s != "abcdef" { + t.Errorf("C.mytext_def = %q, want %q", s, "abcdef") + } + if c := C.myenum; c != 1234 { + t.Errorf("C.myenum = %v, want 1234", c) + } + if c := C.myenum_def; c != 1234 { + t.Errorf("C.myenum_def = %v, want 1234", c) + } + { + const c = C.myenum + if c != 1234 { + t.Errorf("C.myenum as const = %v, want 1234", c) + } + } + { + const c = C.myenum_def + if c != 1234 { + t.Errorf("C.myenum as const = %v, want 1234", c) + } + } + if c := C.myint_def; c != 12345 { + t.Errorf("C.myint_def = %v, want 12345", c) + } + { + const c = C.myint_def + if c != 12345 { + t.Errorf("C.myint as const = %v, want 12345", c) + } + } + + if c := C.myfloat_def; c != 1.5 { + t.Errorf("C.myint_def = %v, want 1.5", c) + } + { + const c = C.myfloat_def + if c != 1.5 { + t.Errorf("C.myint as const = %v, want 1.5", c) + } + } + + if s := C.mystring_def; s != "hello" { + t.Errorf("C.mystring_def = %q, want %q", s, "hello") + } +} + +// issue 6907 + +func test6907(t *testing.T) { + want := "yarn" + if got := C.GoString(C.Issue6907CopyString(want)); got != want { + t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) + } +} + +// issue 7560 + +func test7560(t *testing.T) { + // some mingw don't implement __packed__ correctly. + if C.offset7560() != 1 { + t.Skip("C compiler did not pack struct") + } + + // C.misaligned should have x but then a padding field to get to the end of the struct. + // There should not be a field named 'y'. + var v C.misaligned + rt := reflect.TypeOf(&v).Elem() + if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { + t.Errorf("unexpected fields in C.misaligned:\n") + for i := 0; i < rt.NumField(); i++ { + t.Logf("%+v\n", rt.Field(i)) + } + } +} + +// issue 7786 + +func f() { + var x1 *C.typedef_test7786 + var x2 *C.struct_test7786 + x1 = x2 + x2 = x1 + C.f7786(x1) + C.f7786(x2) + C.g7786(x1) + C.g7786(x2) + + var b1 *C.typedef_body7786 + var b2 *C.struct_body7786 + b1 = b2 + b2 = b1 + C.b7786(b1) + C.b7786(b2) + C.c7786(b1) + C.c7786(b2) + + var u1 *C.typedef_union7786 + var u2 *C.union_union7786 + u1 = u2 + u2 = u1 + C.u7786(u1) + C.u7786(u2) + C.v7786(u1) + C.v7786(u2) +} + +// issue 8092 + +func test8092(t *testing.T) { + tests := []struct { + s string + a, b *C.char + }{ + {"text", &C.text[0], C.ctext()}, + {"data", &C.data[0], C.cdata()}, + } + for _, test := range tests { + if test.a != test.b { + t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b) + } + if got := C.GoString(test.a); got != test.s { + t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s) + } + } +} + +// issues 8368 and 8441 + +func issue8368(one *C.struct_one, two *C.struct_two) { +} + +func issue8441(one *C.one, two *C.two) { + issue8441(two.x, one.x) +} + +// issue 8428 + +var _ = C.struct_issue8428one{ + b: C.char(0), + // The trailing rest field is not available in cgo. + // See issue 11925. + // rest: [0]C.char{}, +} + +var _ = C.struct_issue8428two{ + p: unsafe.Pointer(nil), + b: C.char(0), + rest: [0]C.char{}, +} + +var _ = C.struct_issue8428three{ + w: [1][2][3][0]C.char{}, + x: [2][3][0][1]C.char{}, + y: [3][0][1][2]C.char{}, + z: [0][1][2][3]C.char{}, +} + +// issue 8811 + +func test8811(t *testing.T) { + C.issue8811Execute() +} + +// issue 9557 + +func test9557(t *testing.T) { + // implicitly dereference a Go variable + foo := C.issue9557foo + if v := foo.a; v != 42 { + t.Fatalf("foo.a expected 42, but got %d", v) + } + + // explicitly dereference a C variable + if v := (*C.issue9557foo).a; v != 42 { + t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v) + } + + // implicitly dereference a C variable + if v := C.issue9557foo.a; v != 42 { + t.Fatalf("C.issue9557foo.a expected 42, but is %d", v) + } +} + +// issue 8331 part 1 + +func issue8331a() C.issue8331 { + return issue8331Var +} + +// issue 10303 + +func test10303(t *testing.T, n int) { + if runtime.Compiler == "gccgo" { + t.Skip("gccgo permits C pointers on the stack") + } + + // Run at a few different stack depths just to avoid an unlucky pass + // due to variables ending up on different pages. + if n > 0 { + test10303(t, n-1) + } + if t.Failed() { + return + } + var x, y, z, v, si C.int + var s C.Struct + C.setintstar(&x) + C.setintptr(&y) + C.setvoidptr(unsafe.Pointer(&v)) + s.P = &si + C.setstruct(s) + + if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C int* argument on stack") + } + if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C intptr argument on stack") + } + if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C void* argument on stack") + } + if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { + t.Error("C struct field pointer on stack") + } +} + +// issue 11925 + +func test11925(t *testing.T) { + if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) { + t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{})) + } + if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) { + t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{})) + } +} + +// issue 12030 + +func test12030(t *testing.T) { + buf := (*C.char)(C.malloc(256)) + defer C.free(unsafe.Pointer(buf)) + for _, f := range []float64{1.0, 2.0, 3.14} { + C.issue12030conv(buf, C.double(f)) + got := C.GoString(buf) + if want := fmt.Sprintf("d=%g", f); got != want { + t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want) + } + } +} + +// issue 13402 + +var _ C.complexfloat +var _ C.complexdouble + +// issue 13930 +// Test that cgo's multiple-value special form for +// C function calls works in variable declaration statements. + +var _, _ = C.abs(0) + +// issue 14838 + +func test14838(t *testing.T) { + data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} + cData := C.CBytes(data) + defer C.free(cData) + + if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 { + t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:]) + } +} + +// issue 17065 + +var sink C.int + +func test17065(t *testing.T) { + if runtime.GOOS == "darwin" { + t.Skip("broken on darwin; issue 17065") + } + for i := range C.ii { + sink = C.ii[i] + } +} + +// issue 17537 + +func test17537(t *testing.T) { + v := C.S17537{i: 17537} + if got, want := C.I17537(&v), C.int(17537); got != want { + t.Errorf("got %d, want %d", got, want) + } + + p := (*C.char)(C.malloc(1)) + *p = 17 + if got, want := C.F17537(&p), C.int(17); got != want { + t.Errorf("got %d, want %d", got, want) + } + + C.F18298(nil) + var v18298 C.T18298_2 + C.G18298(C.T18298_1(v18298)) +} + +// issue 17723 + +func testAPI() { + var cs *C.char + cs = C.CString("hello") + defer C.free(unsafe.Pointer(cs)) + var s string + s = C.GoString((*C.char)(C.api_hello)) + s = C.GoStringN((*C.char)(C.api_hello), C.int(6)) + var b []byte + b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6)) + _, _ = s, b + C.cstring_pointer_fun(nil) +} + +// issue 18126 + +func test18126(t *testing.T) { + p := C.malloc(1) + _, err := C.Issue18126C(&p) + C.free(p) + _ = err +} + +// issue 18720 + +func test18720(t *testing.T) { + if got, want := C.HELLO_WORLD, "hello\000world"; got != want { + t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want) + } + + if got, want := C.VAR1, C.int(5); got != want { + t.Errorf("C.VAR1 == %v, expected %v", got, want) + } + + if got, want := *C.ADDR, C.int(5); got != want { + t.Errorf("*C.ADDR == %v, expected %v", got, want) + } + + if got, want := C.CALL, C.int(6); got != want { + t.Errorf("C.CALL == %v, expected %v", got, want) + } + + if got, want := C.CALL, C.int(7); got != want { + t.Errorf("C.CALL == %v, expected %v", got, want) + } + + // Issue 20125. + if got, want := C.SIZE_OF_FOO, 1; got != want { + t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want) + } +} + +// issue 20129 + +func test20129(t *testing.T) { + if C.issue20129 != 0 { + t.Fatal("test is broken") + } + C.issue20129Foo() + if C.issue20129 != 1 { + t.Errorf("got %v but expected %v", C.issue20129, 1) + } + C.issue20129Bar() + if C.issue20129 != 2 { + t.Errorf("got %v but expected %v", C.issue20129, 2) + } +} + +// issue 20369 + +func test20369(t *testing.T) { + if C.XUINT64_MAX != math.MaxUint64 { + t.Fatalf("got %v, want %v", uint64(C.XUINT64_MAX), uint64(math.MaxUint64)) + } +} + +// issue 21668 + +var issue21668_X = C.x21668 + +// issue 21708 + +func test21708(t *testing.T) { + if got, want := C.CAST_TO_INT64, -1; got != want { + t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want) + } +} + +// issue 21809 + +func test21809(t *testing.T) { + longVar := C.long(3) + typedefVar := C.MySigned_t(4) + typedefTypedefVar := C.MySigned2_t(5) + + // all three should be considered identical to `long` + if ret := C.takes_long(longVar); ret != 9 { + t.Errorf("got %v but expected %v", ret, 9) + } + if ret := C.takes_long(typedefVar); ret != 16 { + t.Errorf("got %v but expected %v", ret, 16) + } + if ret := C.takes_long(typedefTypedefVar); ret != 25 { + t.Errorf("got %v but expected %v", ret, 25) + } + + // They should also be identical to the typedef'd type + if ret := C.takes_typedef(longVar); ret != 9 { + t.Errorf("got %v but expected %v", ret, 9) + } + if ret := C.takes_typedef(typedefVar); ret != 16 { + t.Errorf("got %v but expected %v", ret, 16) + } + if ret := C.takes_typedef(typedefTypedefVar); ret != 25 { + t.Errorf("got %v but expected %v", ret, 25) + } +} + +// issue 22906 + +func test22906(t *testing.T) { + var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. + _ = x1 + var x2 C.jclass = 0 + _ = x2 + var x3 C.jthrowable = 0 + _ = x3 + var x4 C.jstring = 0 + _ = x4 + var x5 C.jarray = 0 + _ = x5 + var x6 C.jbooleanArray = 0 + _ = x6 + var x7 C.jbyteArray = 0 + _ = x7 + var x8 C.jcharArray = 0 + _ = x8 + var x9 C.jshortArray = 0 + _ = x9 + var x10 C.jintArray = 0 + _ = x10 + var x11 C.jlongArray = 0 + _ = x11 + var x12 C.jfloatArray = 0 + _ = x12 + var x13 C.jdoubleArray = 0 + _ = x13 + var x14 C.jobjectArray = 0 + _ = x14 + var x15 C.jweak = 0 + _ = x15 +} + +// issue 22958 +// Nothing to run, just make sure this compiles. +var Vissue22958 C.issue22958Type + +func test23356(t *testing.T) { + if got, want := C.a(), C.int(5); got != want { + t.Errorf("C.a() == %v, expected %v", got, want) + } + if got, want := C.r(), C.int(3); got != want { + t.Errorf("C.r() == %v, expected %v", got, want) + } +} + +// issue 23720 + +func Issue23720F() { + var x C.issue23720A + C.issue23720F(x) +} + +// issue 24206 + +func test24206(t *testing.T) { + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH) + } + + if l := len(C.GoString(C.dangerousString1())); l != 123 { + t.Errorf("Incorrect string length - got %d, want 123", l) + } + if l := len(C.GoString(C.dangerousString2())); l != 4096+123 { + t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123) + } +} + +// issue 25143 + +func issue25143sum(ns ...C.int) C.int { + total := C.int(0) + for _, n := range ns { + total += n + } + return total +} + +func test25143(t *testing.T) { + if got, want := issue25143sum(1, 2, 3), C.int(6); got != want { + t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want) + } +} + +// issue 26066 +// Wrong type of constant with GCC 8 and newer. + +func test26066(t *testing.T) { + var i = int64(C.issue26066) + if i != -1 { + t.Errorf("got %d, want -1", i) + } +} + +// issue 26517 +var a C.TypeOne +var b C.TypeTwo + +// issue 27660 +// Stress the interaction between the race detector and cgo in an +// attempt to reproduce the memory corruption described in #27660. +// The bug was very timing sensitive; at the time of writing this +// test would only trigger the bug about once out of every five runs. + +func test27660(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + ints := make([]int, 100) + locks := make([]sync.Mutex, 100) + // Slowly create threads so that ThreadSanitizer is forced to + // frequently resize its SyncClocks. + for i := 0; i < 100; i++ { + go func() { + for ctx.Err() == nil { + // Sleep in C for long enough that it is likely that the runtime + // will retake this goroutine's currently wired P. + C.usleep(1000 /* 1ms */) + runtime.Gosched() // avoid starvation (see #28701) + } + }() + go func() { + // Trigger lots of synchronization and memory reads/writes to + // increase the likelihood that the race described in #27660 + // results in corruption of ThreadSanitizer's internal state + // and thus an assertion failure or segfault. + i := 0 + for ctx.Err() == nil { + j := rand.Intn(100) + locks[j].Lock() + ints[j]++ + locks[j].Unlock() + // Avoid making the loop unpreemptible + // for gccgo. + if i%0x1000000 == 0 { + runtime.Gosched() + } + i++ + } + }() + time.Sleep(time.Millisecond) + } +} + +// issue 28540 + +func twoargsF() { + v := []string{} + C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v))) +} + +// issue 28545 + +func issue28545G(p **C.char) { + C.issue28545F(p, -1, (0)) + C.issue28545F(p, 2+3, complex(1, 1)) + C.issue28545F(p, issue28772Constant, issue28772Constant2) +} + +// issue 28772 part 1 - part 2 in testx.go + +const issue28772Constant = C.issue28772Constant + +// issue 28896 + +func offset(i int) uintptr { + var pi C.innerPacked + var po C.outerPacked + var ui C.innerUnpacked + var uo C.outerUnpacked + switch i { + case 0: + return unsafe.Offsetof(pi.f2) + case 1: + return unsafe.Offsetof(po.g2) + case 2: + return unsafe.Offsetof(ui.f2) + case 3: + return unsafe.Offsetof(uo.g2) + default: + panic("can't happen") + } +} + +func test28896(t *testing.T) { + for i := 0; i < 4; i++ { + c := uintptr(C.offset(C.int(i))) + g := offset(i) + if c != g { + t.Errorf("%d: C: %d != Go %d", i, c, g) + } + } +} + +// issue 29383 +// cgo's /*line*/ comments failed when inserted after '/', +// because the result looked like a "//" comment. +// No runtime test; just make sure it compiles. + +func Issue29383(n, size uint) int { + if ^C.size_t(0)/C.size_t(n) < C.size_t(size) { + return 0 + } + return 0 +} + +// issue 29748 +// Error handling a struct initializer that requires pointer checking. +// Compilation test only, nothing to run. + +var Vissue29748 = C.f29748(&C.S29748{ + nil, +}) + +func Fissue299748() { + C.f29748(&C.S29748{ + nil, + }) +} + +// issue 29781 + +var issue29781X struct{ X int } + +func issue29781F(...int) int { return 0 } + +func issue29781G() { + var p *C.char + C.issue29781F(&p, C.ISSUE29781C+1) + C.issue29781F(nil, (C.int)( + 0)) + C.issue29781F(&p, (C.int)(0)) + C.issue29781F(&p, (C.int)( + 0)) + C.issue29781F(&p, (C.int)(issue29781X. + X)) +} + +// issue 30065 + +func test30065(t *testing.T) { + var a [256]byte + b := []byte("a") + C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1) + if a[0] != 'a' { + t.Errorf("&a failed: got %c, want %c", a[0], 'a') + } + + b = []byte("b") + C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1) + if a[0] != 'b' { + t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b') + } + + d := make([]byte, 256) + b = []byte("c") + C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1) + if d[0] != 'c' { + t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c') + } +} + +// issue 31093 +// No runtime test; just make sure it compiles. + +func Issue31093() { + C.issue31093F(C.ushort(0)) +} + +// issue 32579 + +func test32579(t *testing.T) { + var s [1]C.struct_S32579 + C.memset(unsafe.Pointer(&s[0].data[0]), 1, 1) + if s[0].data[0] != 1 { + t.Errorf("&s[0].data[0] failed: got %d, want %d", s[0].data[0], 1) + } +} diff --git a/libgo/misc/cgo/test/test22906.go b/libgo/misc/cgo/test/test22906.go deleted file mode 100644 index 02bae9c..0000000 --- a/libgo/misc/cgo/test/test22906.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build cgo - -package cgotest - -/* - -// It's going to be hard to include a whole real JVM to test this. -// So we'll simulate a really easy JVM using just the parts we need. - -// This is the relevant part of jni.h. - -struct _jobject; - -typedef struct _jobject *jobject; -typedef jobject jclass; -typedef jobject jthrowable; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; -typedef jarray jobjectArray; - -typedef jobject jweak; - -// Note: jvalue is already a non-pointer type due to it being a C union. - -*/ -import "C" -import ( - "testing" -) - -func test22906(t *testing.T) { - var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. - _ = x1 - var x2 C.jclass = 0 - _ = x2 - var x3 C.jthrowable = 0 - _ = x3 - var x4 C.jstring = 0 - _ = x4 - var x5 C.jarray = 0 - _ = x5 - var x6 C.jbooleanArray = 0 - _ = x6 - var x7 C.jbyteArray = 0 - _ = x7 - var x8 C.jcharArray = 0 - _ = x8 - var x9 C.jshortArray = 0 - _ = x9 - var x10 C.jintArray = 0 - _ = x10 - var x11 C.jlongArray = 0 - _ = x11 - var x12 C.jfloatArray = 0 - _ = x12 - var x13 C.jdoubleArray = 0 - _ = x13 - var x14 C.jobjectArray = 0 - _ = x14 - var x15 C.jweak = 0 - _ = x15 -} diff --git a/libgo/misc/cgo/test/test26213.go b/libgo/misc/cgo/test/test26213.go deleted file mode 100644 index 176a7ec..0000000 --- a/libgo/misc/cgo/test/test26213.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgotest - -import ( - "testing" - - "./issue26213" -) - -func test26213(t *testing.T) { - issue26213.Test26213(t) -} diff --git a/libgo/misc/cgo/test/test27660.go b/libgo/misc/cgo/test/test27660.go deleted file mode 100644 index 0345aa7..0000000 --- a/libgo/misc/cgo/test/test27660.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Stress the interaction between the race detector and cgo in an -// attempt to reproduce the memory corruption described in #27660. -// The bug was very timing sensitive; at the time of writing this -// test would only trigger the bug about once out of every five runs. - -package cgotest - -// #include -import "C" - -import ( - "context" - "math/rand" - "runtime" - "sync" - "testing" - "time" -) - -func test27660(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - ints := make([]int, 100) - locks := make([]sync.Mutex, 100) - // Slowly create threads so that ThreadSanitizer is forced to - // frequently resize its SyncClocks. - for i := 0; i < 100; i++ { - go func() { - for ctx.Err() == nil { - // Sleep in C for long enough that it is likely that the runtime - // will retake this goroutine's currently wired P. - C.usleep(1000 /* 1ms */) - runtime.Gosched() // avoid starvation (see #28701) - } - }() - go func() { - // Trigger lots of synchronization and memory reads/writes to - // increase the likelihood that the race described in #27660 - // results in corruption of ThreadSanitizer's internal state - // and thus an assertion failure or segfault. - i := 0 - for ctx.Err() == nil { - j := rand.Intn(100) - locks[j].Lock() - ints[j]++ - locks[j].Unlock() - // Avoid making the loop unpreemptible - // for gccgo. - if i%0x1000000 == 0 { - runtime.Gosched() - } - i++ - } - }() - time.Sleep(time.Millisecond) - } -} diff --git a/libgo/misc/cgo/test/test_unix.go b/libgo/misc/cgo/test/test_unix.go new file mode 100644 index 0000000..4a23446 --- /dev/null +++ b/libgo/misc/cgo/test/test_unix.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !windows + +package cgotest + +import "syscall" + +var syscall_dot_SIGCHLD = syscall.SIGCHLD diff --git a/libgo/misc/cgo/test/test_windows.go b/libgo/misc/cgo/test/test_windows.go new file mode 100644 index 0000000..7bfb33a --- /dev/null +++ b/libgo/misc/cgo/test/test_windows.go @@ -0,0 +1,9 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import "syscall" + +var syscall_dot_SIGCHLD syscall.Signal diff --git a/libgo/misc/cgo/test/testdata/cgo_linux_test.go b/libgo/misc/cgo/test/testdata/cgo_linux_test.go new file mode 100644 index 0000000..5cef09f --- /dev/null +++ b/libgo/misc/cgo/test/testdata/cgo_linux_test.go @@ -0,0 +1,9 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import "testing" + +func Test9400(t *testing.T) { test9400(t) } diff --git a/libgo/misc/cgo/test/testdata/cgo_test.go b/libgo/misc/cgo/test/testdata/cgo_test.go new file mode 100644 index 0000000..ffa076f --- /dev/null +++ b/libgo/misc/cgo/test/testdata/cgo_test.go @@ -0,0 +1,18 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import "testing" + +// The actual test functions are in non-_test.go files +// so that they can use cgo (import "C"). +// These wrappers are here for gotest to find. + +func Test8756(t *testing.T) { test8756(t) } +func Test9026(t *testing.T) { test9026(t) } +func Test9510(t *testing.T) { test9510(t) } +func Test20266(t *testing.T) { test20266(t) } +func Test26213(t *testing.T) { test26213(t) } +func TestGCC68255(t *testing.T) { testGCC68255(t) } diff --git a/libgo/misc/cgo/test/testdata/gcc68255.go b/libgo/misc/cgo/test/testdata/gcc68255.go new file mode 100644 index 0000000..b431462 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/gcc68255.go @@ -0,0 +1,17 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import ( + "testing" + + "cgotest/gcc68255" +) + +func testGCC68255(t *testing.T) { + if !gcc68255.F() { + t.Error("C global variable was not initialized") + } +} diff --git a/libgo/misc/cgo/test/testdata/gcc68255/a.go b/libgo/misc/cgo/test/testdata/gcc68255/a.go new file mode 100644 index 0000000..e106dee --- /dev/null +++ b/libgo/misc/cgo/test/testdata/gcc68255/a.go @@ -0,0 +1,17 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that it's OK to have C code that does nothing other than +// initialize a global variable. This used to fail with gccgo. + +package gcc68255 + +/* +#include "c.h" +*/ +import "C" + +func F() bool { + return C.v != nil +} diff --git a/libgo/misc/cgo/test/testdata/gcc68255/c.c b/libgo/misc/cgo/test/testdata/gcc68255/c.c new file mode 100644 index 0000000..a4fe193 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/gcc68255/c.c @@ -0,0 +1,8 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +static void f(void) { +} + +void (*v)(void) = f; diff --git a/libgo/misc/cgo/test/testdata/gcc68255/c.h b/libgo/misc/cgo/test/testdata/gcc68255/c.h new file mode 100644 index 0000000..05ecd81 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/gcc68255/c.h @@ -0,0 +1,5 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +extern void (*v)(void); diff --git a/libgo/misc/cgo/test/testdata/issue20266.go b/libgo/misc/cgo/test/testdata/issue20266.go new file mode 100644 index 0000000..9f95086 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue20266.go @@ -0,0 +1,21 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 20266: use -I with a relative path. + +package cgotest + +/* +#cgo CFLAGS: -I issue20266 -Iissue20266 -Ddef20266 +#include "issue20266.h" +*/ +import "C" + +import "testing" + +func test20266(t *testing.T) { + if got, want := C.issue20266, 20266; got != want { + t.Errorf("got %d, want %d", got, want) + } +} diff --git a/libgo/misc/cgo/test/testdata/issue20266/issue20266.h b/libgo/misc/cgo/test/testdata/issue20266/issue20266.h new file mode 100644 index 0000000..8d3258e --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue20266/issue20266.h @@ -0,0 +1,9 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#define issue20266 20266 + +#ifndef def20266 +#error "expected def20266 to be defined" +#endif diff --git a/libgo/misc/cgo/test/testdata/issue23555.go b/libgo/misc/cgo/test/testdata/issue23555.go new file mode 100644 index 0000000..4e944b5 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue23555.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that we can have two identical cgo packages in a single binary. +// No runtime test; just make sure it compiles. + +package cgotest + +import _ "cgotest/issue23555a" +import _ "cgotest/issue23555b" diff --git a/libgo/misc/cgo/test/testdata/issue23555a/a.go b/libgo/misc/cgo/test/testdata/issue23555a/a.go new file mode 100644 index 0000000..cb6626b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue23555a/a.go @@ -0,0 +1,12 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue23555 + +// #include +import "C" + +func X() { + C.free(C.malloc(10)) +} diff --git a/libgo/misc/cgo/test/testdata/issue23555b/a.go b/libgo/misc/cgo/test/testdata/issue23555b/a.go new file mode 100644 index 0000000..cb6626b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue23555b/a.go @@ -0,0 +1,12 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue23555 + +// #include +import "C" + +func X() { + C.free(C.malloc(10)) +} diff --git a/libgo/misc/cgo/test/testdata/issue24161_darwin_test.go b/libgo/misc/cgo/test/testdata/issue24161_darwin_test.go new file mode 100644 index 0000000..64f4442 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161_darwin_test.go @@ -0,0 +1,39 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// See issue21897.go and golang.org/issue/26475 for why this is +// skipped in race mode. +// +// TODO(austin): Once support for macOS 10.10 is dropped, remove the +// race constraint. See golang.org/issue/26513. + +// +build !race + +package cgotest + +import ( + "testing" + + "cgotest/issue24161arg" + "cgotest/issue24161e0" + "cgotest/issue24161e1" + "cgotest/issue24161e2" + "cgotest/issue24161res" +) + +func Test24161Arg(t *testing.T) { + issue24161arg.Test(t) +} +func Test24161Res(t *testing.T) { + issue24161res.Test(t) +} +func Test24161Example0(t *testing.T) { + issue24161e0.Test(t) +} +func Test24161Example1(t *testing.T) { + issue24161e1.Test(t) +} +func Test24161Example2(t *testing.T) { + issue24161e2.Test(t) +} diff --git a/libgo/misc/cgo/test/testdata/issue24161arg/def.go b/libgo/misc/cgo/test/testdata/issue24161arg/def.go new file mode 100644 index 0000000..d33479a --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161arg/def.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161arg + +/* +#cgo LDFLAGS: -framework CoreFoundation +#include +*/ +import "C" + +func test24161array() C.CFArrayRef { + return C.CFArrayCreate(0, nil, 0, nil) +} diff --git a/libgo/misc/cgo/test/testdata/issue24161arg/use.go b/libgo/misc/cgo/test/testdata/issue24161arg/use.go new file mode 100644 index 0000000..3e74944 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161arg/use.go @@ -0,0 +1,19 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161arg + +/* +#cgo LDFLAGS: -framework CoreFoundation +#include +*/ +import "C" +import "testing" + +func Test(t *testing.T) { + a := test24161array() + C.CFArrayCreateCopy(0, a) +} diff --git a/libgo/misc/cgo/test/testdata/issue24161e0/main.go b/libgo/misc/cgo/test/testdata/issue24161e0/main.go new file mode 100644 index 0000000..cbc1dee --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161e0/main.go @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161e0 + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework CoreFoundation -framework Security +#include +#include +#include +#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 + typedef CFStringRef SecKeyAlgorithm; + static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} + #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() + static SecKeyAlgorithm foo(void){return NULL;} +#endif +*/ +import "C" +import "testing" + +func f1() { + C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) +} + +func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/testdata/issue24161e1/main.go b/libgo/misc/cgo/test/testdata/issue24161e1/main.go new file mode 100644 index 0000000..eb48fc0 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161e1/main.go @@ -0,0 +1,38 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161e1 + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework CoreFoundation -framework Security +#include +#include +#include +#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 + typedef CFStringRef SecKeyAlgorithm; + static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} + #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() + static SecKeyAlgorithm foo(void){return NULL;} +#endif +*/ +import "C" +import ( + "fmt" + "testing" +) + +func f1() { + C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) +} + +func f2(e C.CFErrorRef) { + if desc := C.CFErrorCopyDescription(e); desc != 0 { + fmt.Println(desc) + } +} + +func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/testdata/issue24161e2/main.go b/libgo/misc/cgo/test/testdata/issue24161e2/main.go new file mode 100644 index 0000000..1951c86 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161e2/main.go @@ -0,0 +1,40 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161e2 + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework CoreFoundation -framework Security +#include +#include +#include +#if TARGET_OS_IPHONE == 0 && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200 + typedef CFStringRef SecKeyAlgorithm; + static CFDataRef SecKeyCreateSignature(SecKeyRef key, SecKeyAlgorithm algorithm, CFDataRef dataToSign, CFErrorRef *error){return NULL;} + #define kSecKeyAlgorithmECDSASignatureDigestX962SHA1 foo() + static SecKeyAlgorithm foo(void){return NULL;} +#endif +*/ +import "C" +import ( + "fmt" + "testing" +) + +var _ C.CFStringRef + +func f1() { + C.SecKeyCreateSignature(0, C.kSecKeyAlgorithmECDSASignatureDigestX962SHA1, 0, nil) +} + +func f2(e C.CFErrorRef) { + if desc := C.CFErrorCopyDescription(e); desc != 0 { + fmt.Println(desc) + } +} + +func Test(t *testing.T) {} diff --git a/libgo/misc/cgo/test/testdata/issue24161res/restype.go b/libgo/misc/cgo/test/testdata/issue24161res/restype.go new file mode 100644 index 0000000..e5719f2 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue24161res/restype.go @@ -0,0 +1,23 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin + +package issue24161res + +/* +#cgo LDFLAGS: -framework CoreFoundation +#include +*/ +import "C" +import ( + "reflect" + "testing" +) + +func Test(t *testing.T) { + if k := reflect.TypeOf(C.CFArrayCreate(0, nil, 0, nil)).Kind(); k != reflect.Uintptr { + t.Fatalf("bad kind %s\n", k) + } +} diff --git a/libgo/misc/cgo/test/testdata/issue26213/jni.h b/libgo/misc/cgo/test/testdata/issue26213/jni.h new file mode 100644 index 0000000..0c76979 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26213/jni.h @@ -0,0 +1,29 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// It's going to be hard to include a whole real JVM to test this. +// So we'll simulate a really easy JVM using just the parts we need. + +// This is the relevant part of jni.h. + +// On Android NDK16, jobject is defined like this in C and C++ +typedef void* jobject; + +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +typedef jobject jweak; + +// Note: jvalue is already a non-pointer type due to it being a C union. diff --git a/libgo/misc/cgo/test/testdata/issue26213/test26213.go b/libgo/misc/cgo/test/testdata/issue26213/test26213.go new file mode 100644 index 0000000..5d1f637 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26213/test26213.go @@ -0,0 +1,46 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue26213 + +/* +#include "jni.h" +*/ +import "C" +import ( + "testing" +) + +func Test26213(t *testing.T) { + var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. + _ = x1 + var x2 C.jclass = 0 + _ = x2 + var x3 C.jthrowable = 0 + _ = x3 + var x4 C.jstring = 0 + _ = x4 + var x5 C.jarray = 0 + _ = x5 + var x6 C.jbooleanArray = 0 + _ = x6 + var x7 C.jbyteArray = 0 + _ = x7 + var x8 C.jcharArray = 0 + _ = x8 + var x9 C.jshortArray = 0 + _ = x9 + var x10 C.jintArray = 0 + _ = x10 + var x11 C.jlongArray = 0 + _ = x11 + var x12 C.jfloatArray = 0 + _ = x12 + var x13 C.jdoubleArray = 0 + _ = x13 + var x14 C.jobjectArray = 0 + _ = x14 + var x15 C.jweak = 0 + _ = x15 +} diff --git a/libgo/misc/cgo/test/testdata/issue26430.go b/libgo/misc/cgo/test/testdata/issue26430.go new file mode 100644 index 0000000..14c7a7c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26430.go @@ -0,0 +1,10 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 26430: incomplete typedef leads to inconsistent typedefs error. +// No runtime test; just make sure it compiles. + +package cgotest + +import _ "cgotest/issue26430" diff --git a/libgo/misc/cgo/test/testdata/issue26430/a.go b/libgo/misc/cgo/test/testdata/issue26430/a.go new file mode 100644 index 0000000..fbaa46b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26430/a.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package a + +// typedef struct S ST; +// static ST* F() { return 0; } +import "C" + +func F1() { + C.F() +} diff --git a/libgo/misc/cgo/test/testdata/issue26430/b.go b/libgo/misc/cgo/test/testdata/issue26430/b.go new file mode 100644 index 0000000..a7c527c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26430/b.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package a + +// typedef struct S ST; +// struct S { int f; }; +import "C" + +func F2(p *C.ST) { + p.f = 1 +} diff --git a/libgo/misc/cgo/test/testdata/issue26743.go b/libgo/misc/cgo/test/testdata/issue26743.go new file mode 100644 index 0000000..000fb2b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26743.go @@ -0,0 +1,10 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 26743: typedef of uint leads to inconsistent typedefs error. +// No runtime test; just make sure it compiles. + +package cgotest + +import _ "cgotest/issue26743" diff --git a/libgo/misc/cgo/test/testdata/issue26743/a.go b/libgo/misc/cgo/test/testdata/issue26743/a.go new file mode 100644 index 0000000..a3df179 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26743/a.go @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue26743 + +// typedef unsigned int uint; +// int C1(uint x) { return x; } +import "C" + +var V1 = C.C1(0) diff --git a/libgo/misc/cgo/test/testdata/issue26743/b.go b/libgo/misc/cgo/test/testdata/issue26743/b.go new file mode 100644 index 0000000..c5f1ae4 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue26743/b.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue26743 + +import "C" + +var V2 C.uint diff --git a/libgo/misc/cgo/test/testdata/issue27054/egl.h b/libgo/misc/cgo/test/testdata/issue27054/egl.h new file mode 100644 index 0000000..33a759e --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue27054/egl.h @@ -0,0 +1,7 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This is the relevant part of EGL/egl.h. + +typedef void *EGLDisplay; diff --git a/libgo/misc/cgo/test/testdata/issue27054/test27054.go b/libgo/misc/cgo/test/testdata/issue27054/test27054.go new file mode 100644 index 0000000..186f5bd --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue27054/test27054.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue27054 + +/* +#include "egl.h" +*/ +import "C" +import ( + "testing" +) + +func Test27054(t *testing.T) { + var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type. +} diff --git a/libgo/misc/cgo/test/testdata/issue27340.go b/libgo/misc/cgo/test/testdata/issue27340.go new file mode 100644 index 0000000..337550f --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue27340.go @@ -0,0 +1,12 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Failed to resolve typedefs consistently. +// No runtime test; just make sure it compiles. + +package cgotest + +import "cgotest/issue27340" + +var issue27340Var = issue27340.Issue27340GoFunc diff --git a/libgo/misc/cgo/test/testdata/issue27340/a.go b/libgo/misc/cgo/test/testdata/issue27340/a.go new file mode 100644 index 0000000..f5b120c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue27340/a.go @@ -0,0 +1,42 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Failed to resolve typedefs consistently. +// No runtime test; just make sure it compiles. +// In separate directory to isolate #pragma GCC diagnostic. + +package issue27340 + +// We use the #pragma to avoid a compiler warning about incompatible +// pointer types, because we generate code passing a struct ptr rather +// than using the typedef. This warning is expected and does not break +// a normal build. +// We can only disable -Wincompatible-pointer-types starting with GCC 5. + +// #if __GNU_MAJOR__ >= 5 +// +// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" +// +// typedef struct { +// int a; +// } issue27340Struct, *issue27340Ptr; +// +// static void issue27340CFunc(issue27340Ptr p) {} +// +// #else /* _GNU_MAJOR_ < 5 */ +// +// typedef struct { +// int a; +// } issue27340Struct; +// +// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; } +// +// static void issue27340CFunc(issue27340Struct *p) {} +// #endif /* _GNU_MAJOR_ < 5 */ +import "C" + +func Issue27340GoFunc() { + var s C.issue27340Struct + C.issue27340CFunc(C.issue27340Ptr(&s)) +} diff --git a/libgo/misc/cgo/test/testdata/issue29563.go b/libgo/misc/cgo/test/testdata/issue29563.go new file mode 100644 index 0000000..84def3c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue29563.go @@ -0,0 +1,12 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !windows + +// Issue 29563: internal linker fails on duplicate weak symbols. +// No runtime test; just make sure it compiles. + +package cgotest + +import _ "cgotest/issue29563" diff --git a/libgo/misc/cgo/test/testdata/issue29563/weak.go b/libgo/misc/cgo/test/testdata/issue29563/weak.go new file mode 100644 index 0000000..21cf635c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue29563/weak.go @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue29563 + +//int foo1(); +//int foo2(); +import "C" + +func Bar() int { + return int(C.foo1()) + int(C.foo2()) +} diff --git a/libgo/misc/cgo/test/testdata/issue29563/weak1.c b/libgo/misc/cgo/test/testdata/issue29563/weak1.c new file mode 100644 index 0000000..86a2273 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue29563/weak1.c @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +extern int weaksym __attribute__((__weak__)); +int weaksym = 42; + +int foo1() +{ + return weaksym; +} diff --git a/libgo/misc/cgo/test/testdata/issue29563/weak2.c b/libgo/misc/cgo/test/testdata/issue29563/weak2.c new file mode 100644 index 0000000..e01eae8 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue29563/weak2.c @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +extern int weaksym __attribute__((__weak__)); +int weaksym = 42; + +int foo2() +{ + return weaksym; +} diff --git a/libgo/misc/cgo/test/testdata/issue8756.go b/libgo/misc/cgo/test/testdata/issue8756.go new file mode 100644 index 0000000..406c64c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue8756.go @@ -0,0 +1,17 @@ +package cgotest + +/* +#cgo LDFLAGS: -lm +#include +*/ +import "C" +import ( + "testing" + + "cgotest/issue8756" +) + +func test8756(t *testing.T) { + issue8756.Pow() + C.pow(1, 2) +} diff --git a/libgo/misc/cgo/test/testdata/issue8756/issue8756.go b/libgo/misc/cgo/test/testdata/issue8756/issue8756.go new file mode 100644 index 0000000..5f6b777 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue8756/issue8756.go @@ -0,0 +1,11 @@ +package issue8756 + +/* +#cgo LDFLAGS: -lm +#include +*/ +import "C" + +func Pow() { + C.pow(1, 2) +} diff --git a/libgo/misc/cgo/test/testdata/issue8828.go b/libgo/misc/cgo/test/testdata/issue8828.go new file mode 100644 index 0000000..0bca0f2 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue8828.go @@ -0,0 +1,16 @@ +// compile + +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 8828: compiling a file with -compiler=gccgo fails if a .c file +// has the same name as compiled directory. + +package cgotest + +import "cgotest/issue8828" + +func p() { + issue8828.Bar() +} diff --git a/libgo/misc/cgo/test/testdata/issue8828/issue8828.c b/libgo/misc/cgo/test/testdata/issue8828/issue8828.c new file mode 100644 index 0000000..27ec23a --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue8828/issue8828.c @@ -0,0 +1,7 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +void foo() +{ +} diff --git a/libgo/misc/cgo/test/testdata/issue8828/trivial.go b/libgo/misc/cgo/test/testdata/issue8828/trivial.go new file mode 100644 index 0000000..e7b9a4e --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue8828/trivial.go @@ -0,0 +1,8 @@ +package issue8828 + +//void foo(); +import "C" + +func Bar() { + C.foo() +} diff --git a/libgo/misc/cgo/test/testdata/issue9026.go b/libgo/misc/cgo/test/testdata/issue9026.go new file mode 100644 index 0000000..3f48881 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9026.go @@ -0,0 +1,9 @@ +package cgotest + +import ( + "testing" + + "cgotest/issue9026" +) + +func test9026(t *testing.T) { issue9026.Test(t) } diff --git a/libgo/misc/cgo/test/testdata/issue9026/issue9026.go b/libgo/misc/cgo/test/testdata/issue9026/issue9026.go new file mode 100644 index 0000000..149c265 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9026/issue9026.go @@ -0,0 +1,36 @@ +package issue9026 + +// This file appears in its own package since the assertion tests the +// per-package counter used to create fresh identifiers. + +/* +typedef struct {} git_merge_file_input; + +typedef struct {} git_merge_file_options; + +void git_merge_file( + git_merge_file_input *in, + git_merge_file_options *opts) {} +*/ +import "C" +import ( + "fmt" + "testing" +) + +func Test(t *testing.T) { + var in C.git_merge_file_input + var opts *C.git_merge_file_options + C.git_merge_file(&in, opts) + + // Test that the generated type names are deterministic. + // (Previously this would fail about 10% of the time.) + // + // Brittle: the assertion may fail spuriously when the algorithm + // changes, but should remain stable otherwise. + got := fmt.Sprintf("%T %T", in, opts) + want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0" + if got != want { + t.Errorf("Non-deterministic type names: got %s, want %s", got, want) + } +} diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_386.s b/libgo/misc/cgo/test/testdata/issue9400/asm_386.s new file mode 100644 index 0000000..7f158b5 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_386.s @@ -0,0 +1,27 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 + MOVL $·Baton(SB), BX + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADDL $(1024 * 8), SP + + // Ask signaller to setgid + MOVL $1, (BX) + + // Wait for setgid completion +loop: + PAUSE + MOVL (BX), AX + CMPL AX, $0 + JNE loop + + // Restore stack + SUBL $(1024 * 8), SP + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_amd64x.s b/libgo/misc/cgo/test/testdata/issue9400/asm_amd64x.s new file mode 100644 index 0000000..48b8619 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_amd64x.s @@ -0,0 +1,27 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64 amd64p32 +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADDQ $(1024 * 8), SP + + // Ask signaller to setgid + MOVL $1, ·Baton(SB) + + // Wait for setgid completion +loop: + PAUSE + MOVL ·Baton(SB), AX + CMPL AX, $0 + JNE loop + + // Restore stack + SUBQ $(1024 * 8), SP + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_arm.s b/libgo/misc/cgo/test/testdata/issue9400/asm_arm.s new file mode 100644 index 0000000..96c2785 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_arm.s @@ -0,0 +1,39 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +TEXT cas<>(SB),NOSPLIT,$0 + MOVW $0xffff0fc0, R15 // R15 is PC + +TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 + // Save link register + MOVW R14, R4 + + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADD $(1024 * 8), R13 + + // Ask signaller to setgid + MOVW $·Baton(SB), R2 +storeloop: + MOVW 0(R2), R0 + MOVW $1, R1 + BL cas<>(SB) + BCC storeloop + + // Wait for setgid completion +loop: + MOVW $0, R0 + MOVW $0, R1 + BL cas<>(SB) + BCC loop + + // Restore stack + SUB $(1024 * 8), R13 + + MOVW R4, R14 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_arm64.s b/libgo/misc/cgo/test/testdata/issue9400/asm_arm64.s new file mode 100644 index 0000000..2ebbfcc --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_arm64.s @@ -0,0 +1,39 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 + // Save link register + MOVD R30, R9 + + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADD $(1024 * 8), RSP + + // Ask signaller to setgid + MOVD $·Baton(SB), R0 + MOVD $1, R1 +storeloop: + LDAXRW (R0), R2 + STLXRW R1, (R0), R3 + CBNZ R3, storeloop + + // Wait for setgid completion + MOVW $0, R1 + MOVW $0, R2 +loop: + LDAXRW (R0), R3 + CMPW R1, R3 + BNE loop + STLXRW R2, (R0), R3 + CBNZ R3, loop + + // Restore stack + SUB $(1024 * 8), RSP + + MOVD R9, R30 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_mips64x.s b/libgo/misc/cgo/test/testdata/issue9400/asm_mips64x.s new file mode 100644 index 0000000..63dc906 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_mips64x.s @@ -0,0 +1,33 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips64 mips64le +// +build !gccgo + +#include "textflag.h" + +#define SYNC WORD $0xf + +TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADDV $(1024*8), R29 + + // Ask signaller to setgid + MOVW $1, R1 + SYNC + MOVW R1, ·Baton(SB) + SYNC + + // Wait for setgid completion +loop: + SYNC + MOVW ·Baton(SB), R1 + OR R2, R2, R2 // hint that we're in a spin loop + BNE R1, loop + SYNC + + // Restore stack + ADDV $(-1024*8), R29 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_mipsx.s b/libgo/misc/cgo/test/testdata/issue9400/asm_mipsx.s new file mode 100644 index 0000000..7a92735 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_mipsx.s @@ -0,0 +1,31 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build mips mipsle +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADDU $(1024*8), R29 + + // Ask signaller to setgid + MOVW $1, R1 + SYNC + MOVW R1, ·Baton(SB) + SYNC + + // Wait for setgid completion +loop: + SYNC + MOVW ·Baton(SB), R1 + OR R2, R2, R2 // hint that we're in a spin loop + BNE R1, loop + SYNC + + // Restore stack + ADDU $(-1024*8), R29 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_ppc64x.s b/libgo/misc/cgo/test/testdata/issue9400/asm_ppc64x.s new file mode 100644 index 0000000..c88ec3b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_ppc64x.s @@ -0,0 +1,32 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ppc64 ppc64le +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0 + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADD $(1024 * 8), R1 + + // Ask signaller to setgid + MOVW $1, R3 + SYNC + MOVW R3, ·Baton(SB) + + // Wait for setgid completion +loop: + SYNC + MOVW ·Baton(SB), R3 + CMP R3, $0 + // Hint that we're in a spin loop + OR R1, R1, R1 + BNE loop + ISYNC + + // Restore stack + SUB $(1024 * 8), R1 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/asm_s390x.s b/libgo/misc/cgo/test/testdata/issue9400/asm_s390x.s new file mode 100644 index 0000000..fc9ad72 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/asm_s390x.s @@ -0,0 +1,26 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +TEXT ·RewindAndSetgid(SB),NOSPLIT,$0-0 + // Rewind stack pointer so anything that happens on the stack + // will clobber the test pattern created by the caller + ADD $(1024 * 8), R15 + + // Ask signaller to setgid + MOVD $·Baton(SB), R5 + MOVW $1, 0(R5) + + // Wait for setgid completion +loop: + SYNC + MOVW ·Baton(SB), R3 + CMPBNE R3, $0, loop + + // Restore stack + SUB $(1024 * 8), R15 + RET diff --git a/libgo/misc/cgo/test/testdata/issue9400/gccgo.go b/libgo/misc/cgo/test/testdata/issue9400/gccgo.go new file mode 100644 index 0000000..a9b62b0 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/gccgo.go @@ -0,0 +1,26 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gccgo + +package issue9400 + +import ( + "runtime" + "sync/atomic" +) + +// The test for the gc compiler resets the stack pointer so that the +// stack gets modified. We don't have a way to do that for gccgo +// without writing more assembly code, which we haven't bothered to +// do. So this is not much of a test. + +var Baton int32 + +func RewindAndSetgid() { + atomic.StoreInt32(&Baton, 1) + for atomic.LoadInt32(&Baton) != 0 { + runtime.Gosched() + } +} diff --git a/libgo/misc/cgo/test/testdata/issue9400/stubs.go b/libgo/misc/cgo/test/testdata/issue9400/stubs.go new file mode 100644 index 0000000..e431c5a --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400/stubs.go @@ -0,0 +1,11 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gc + +package issue9400 + +var Baton int32 + +func RewindAndSetgid() diff --git a/libgo/misc/cgo/test/testdata/issue9400_linux.go b/libgo/misc/cgo/test/testdata/issue9400_linux.go new file mode 100644 index 0000000..e94a9bb --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9400_linux.go @@ -0,0 +1,58 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that SIGSETXID runs on signal stack, since it's likely to +// overflow if it runs on the Go stack. + +package cgotest + +/* +#include +#include +*/ +import "C" + +import ( + "runtime" + "sync/atomic" + "testing" + + "cgotest/issue9400" +) + +func test9400(t *testing.T) { + // We synchronize through a shared variable, so we need two procs + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) + + // Start signaller + atomic.StoreInt32(&issue9400.Baton, 0) + go func() { + // Wait for RewindAndSetgid + for atomic.LoadInt32(&issue9400.Baton) == 0 { + runtime.Gosched() + } + // Broadcast SIGSETXID + runtime.LockOSThread() + C.setgid(0) + // Indicate that signalling is done + atomic.StoreInt32(&issue9400.Baton, 0) + }() + + // Grow the stack and put down a test pattern + const pattern = 0x123456789abcdef + var big [1024]uint64 // len must match assembly + for i := range big { + big[i] = pattern + } + + // Temporarily rewind the stack and trigger SIGSETXID + issue9400.RewindAndSetgid() + + // Check test pattern + for i := range big { + if big[i] != pattern { + t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern)) + } + } +} diff --git a/libgo/misc/cgo/test/testdata/issue9510.go b/libgo/misc/cgo/test/testdata/issue9510.go new file mode 100644 index 0000000..2c79fab --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9510.go @@ -0,0 +1,24 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that we can link together two different cgo packages that both +// use the same libgcc function. + +package cgotest + +import ( + "runtime" + "testing" + + "cgotest/issue9510a" + "cgotest/issue9510b" +) + +func test9510(t *testing.T) { + if runtime.GOARCH == "arm" { + t.Skip("skipping because libgcc may be a Thumb library") + } + issue9510a.F(1, 1) + issue9510b.F(1, 1) +} diff --git a/libgo/misc/cgo/test/testdata/issue9510a/a.go b/libgo/misc/cgo/test/testdata/issue9510a/a.go new file mode 100644 index 0000000..1a5224b --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9510a/a.go @@ -0,0 +1,15 @@ +package issue9510a + +/* +static double csquare(double a, double b) { + __complex__ double d; + __real__ d = a; + __imag__ d = b; + return __real__ (d * d); +} +*/ +import "C" + +func F(a, b float64) float64 { + return float64(C.csquare(C.double(a), C.double(b))) +} diff --git a/libgo/misc/cgo/test/testdata/issue9510b/b.go b/libgo/misc/cgo/test/testdata/issue9510b/b.go new file mode 100644 index 0000000..5016b39 --- /dev/null +++ b/libgo/misc/cgo/test/testdata/issue9510b/b.go @@ -0,0 +1,15 @@ +package issue9510b + +/* +static double csquare(double a, double b) { + __complex__ double d; + __real__ d = a; + __imag__ d = b; + return __real__ (d * d); +} +*/ +import "C" + +func F(a, b float64) float64 { + return float64(C.csquare(C.double(a), C.double(b))) +} diff --git a/libgo/misc/cgo/test/testdata/test26213.go b/libgo/misc/cgo/test/testdata/test26213.go new file mode 100644 index 0000000..c80032c --- /dev/null +++ b/libgo/misc/cgo/test/testdata/test26213.go @@ -0,0 +1,15 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgotest + +import ( + "testing" + + "cgotest/issue26213" +) + +func test26213(t *testing.T) { + issue26213.Test26213(t) +} diff --git a/libgo/misc/cgo/test/testx.go b/libgo/misc/cgo/test/testx.go new file mode 100644 index 0000000..67def90 --- /dev/null +++ b/libgo/misc/cgo/test/testx.go @@ -0,0 +1,519 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test cases for cgo. +// Both the import "C" prologue and the main file are sorted by issue number. +// This file contains //export directives on Go functions +// and so it must NOT contain C definitions (only declarations). +// See test.go for C definitions. + +package cgotest + +import ( + "runtime" + "runtime/debug" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + "unsafe" +) + +/* +// threads +extern void doAdd(int, int); + +// issue 1328 +extern void BackIntoGo(void); +void IntoC(void); + +// issue 1560 +// mysleep returns the absolute start time in ms. +long long mysleep(int seconds); + +// twoSleep returns the absolute start time of the first sleep +// in ms. +long long twoSleep(int); + +// issue 3775 +void lockOSThreadCallback(void); +inline static void lockOSThreadC(void) +{ + lockOSThreadCallback(); +} +int usleep(unsigned usec); + +// issue 4054 part 2 - part 1 in test.go +typedef enum { + A = 0, + B, + C, + D, + E, + F, + G, + H, + II, + J, +} issue4054b; + +// issue 5548 + +extern int issue5548_in_c(void); + +// issue 6833 + +extern unsigned long long issue6833Func(unsigned int, unsigned long long); + +// issue 6907 + +extern int CheckIssue6907C(_GoString_); + +// issue 7665 + +extern void f7665(void); + +// issue 7978 +// Stack tracing didn't work during cgo code after calling a Go +// callback. Make sure GC works and the stack trace is correct. + +#include + +void issue7978cb(void); + +// use ugly atomic variable sync since that doesn't require calling back into +// Go code or OS dependencies +static void issue7978c(uint32_t *sync) { + while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0) + ; + __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST); + while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2) + ; + issue7978cb(); + __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST); + while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6) + ; +} + +// issue 8331 part 2 - part 1 in test.go +// A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. +#include "issue8331.h" + +// issue 20910 +void callMulti(void); + +// issue 28772 part 2 - part 1 in issuex.go +#define issue28772Constant2 2 + +*/ +import "C" + +// exports + +//export ReturnIntLong +func ReturnIntLong() (int, C.long) { + return 1, 2 +} + +//export gc +func gc() { + runtime.GC() +} + +// threads + +var sum struct { + sync.Mutex + i int +} + +//export Add +func Add(x int) { + defer func() { + recover() + }() + sum.Lock() + sum.i += x + sum.Unlock() + var p *int + *p = 2 +} + +func testCthread(t *testing.T) { + if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add") + } + sum.i = 0 + C.doAdd(10, 6) + + want := 10 * (10 - 1) / 2 * 6 + if sum.i != want { + t.Fatalf("sum=%d, want %d", sum.i, want) + } +} + +// issue 1328 + +//export BackIntoGo +func BackIntoGo() { + x := 1 + + for i := 0; i < 10000; i++ { + xvariadic(x) + if x != 1 { + panic("x is not 1?") + } + } +} + +func xvariadic(x ...interface{}) { +} + +func test1328(t *testing.T) { + C.IntoC() +} + +// issue 1560 + +var sleepDone = make(chan int64) + +// parallelSleep returns the absolute difference between the start time +// of the two sleeps. +func parallelSleep(n int) int64 { + t := int64(C.twoSleep(C.int(n))) - <-sleepDone + if t < 0 { + return -t + } + return t +} + +//export BackgroundSleep +func BackgroundSleep(n int32) { + go func() { + sleepDone <- int64(C.mysleep(C.int(n))) + }() +} + +func testParallelSleep(t *testing.T) { + sleepSec := 1 + dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond + t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt) + // bug used to run sleeps in serial, producing a 2*sleepSec-second delay. + // we detect if the start times of those sleeps are > 0.5*sleepSec-second. + if dt >= time.Duration(sleepSec)*time.Second/2 { + t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds()) + } +} + +// issue 2462 + +//export exportbyte +func exportbyte() byte { + return 0 +} + +//export exportbool +func exportbool() bool { + return false +} + +//export exportrune +func exportrune() rune { + return 0 +} + +//export exporterror +func exporterror() error { + return nil +} + +//export exportint +func exportint() int { + return 0 +} + +//export exportuint +func exportuint() uint { + return 0 +} + +//export exportuintptr +func exportuintptr() uintptr { + return (uintptr)(0) +} + +//export exportint8 +func exportint8() int8 { + return 0 +} + +//export exportuint8 +func exportuint8() uint8 { + return 0 +} + +//export exportint16 +func exportint16() int16 { + return 0 +} + +//export exportuint16 +func exportuint16() uint16 { + return 0 +} + +//export exportint32 +func exportint32() int32 { + return 0 +} + +//export exportuint32 +func exportuint32() uint32 { + return 0 +} + +//export exportint64 +func exportint64() int64 { + return 0 +} + +//export exportuint64 +func exportuint64() uint64 { + return 0 +} + +//export exportfloat32 +func exportfloat32() float32 { + return 0 +} + +//export exportfloat64 +func exportfloat64() float64 { + return 0 +} + +//export exportcomplex64 +func exportcomplex64() complex64 { + return 0 +} + +//export exportcomplex128 +func exportcomplex128() complex128 { + return 0 +} + +// issue 3741 + +//export exportSliceIn +func exportSliceIn(s []byte) bool { + return len(s) == cap(s) +} + +//export exportSliceOut +func exportSliceOut() []byte { + return []byte{1} +} + +//export exportSliceInOut +func exportSliceInOut(s []byte) []byte { + return s +} + +// issue 3775 + +func init() { + if runtime.GOOS == "android" { + return + } + // Same as test3775 but run during init so that + // there are two levels of internal runtime lock + // (1 for init, 1 for cgo). + // This would have been broken by CL 11663043. + C.lockOSThreadC() +} + +func test3775(t *testing.T) { + if runtime.GOOS == "android" { + return + } + // Used to panic because of the UnlockOSThread below. + C.lockOSThreadC() +} + +//export lockOSThreadCallback +func lockOSThreadCallback() { + runtime.LockOSThread() + runtime.UnlockOSThread() + go C.usleep(10000) + runtime.Gosched() +} + +// issue 4054 part 2 - part 1 in test.go + +var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J} + +//export issue5548FromC +func issue5548FromC(s string, i int) int { + if len(s) == 4 && s == "test" && i == 42 { + return 12345 + } + println("got", len(s), i) + return 9876 +} + +func test5548(t *testing.T) { + if x := C.issue5548_in_c(); x != 12345 { + t.Errorf("issue5548_in_c = %d, want %d", x, 12345) + } +} + +// issue 6833 + +//export GoIssue6833Func +func GoIssue6833Func(aui uint, aui64 uint64) uint64 { + return aui64 + uint64(aui) +} + +func test6833(t *testing.T) { + ui := 7 + ull := uint64(0x4000300020001000) + v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull))) + exp := uint64(ui) + ull + if v != exp { + t.Errorf("issue6833Func() returns %x, expected %x", v, exp) + } +} + +// issue 6907 + +const CString = "C string" + +//export CheckIssue6907Go +func CheckIssue6907Go(s string) C.int { + if s == CString { + return 1 + } + return 0 +} + +func test6907Go(t *testing.T) { + if got := C.CheckIssue6907C(CString); got != 1 { + t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1) + } +} + +// issue 7665 + +//export f7665 +func f7665() {} + +var bad7665 unsafe.Pointer = C.f7665 +var good7665 uintptr = uintptr(C.f7665) + +func test7665(t *testing.T) { + if bad7665 == nil || uintptr(bad7665) != good7665 { + t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665) + } +} + +// issue 7978 + +var issue7978sync uint32 + +func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) { + runtime.GC() + buf := make([]byte, 65536) + trace := string(buf[:runtime.Stack(buf, true)]) + for _, goroutine := range strings.Split(trace, "\n\n") { + if strings.Contains(goroutine, "test.issue7978go") { + trace := strings.Split(goroutine, "\n") + // look for the expected function in the stack + for i := 0; i < depth; i++ { + if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) { + t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine) + return + } + if strings.Contains(trace[1+2*i], wantFunc) { + return + } + } + t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine) + return + } + } + t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace) +} + +func issue7978wait(store uint32, wait uint32) { + if store != 0 { + atomic.StoreUint32(&issue7978sync, store) + } + for atomic.LoadUint32(&issue7978sync) != wait { + runtime.Gosched() + } +} + +//export issue7978cb +func issue7978cb() { + // Force a stack growth from the callback to put extra + // pressure on the runtime. See issue #17785. + growStack(64) + issue7978wait(3, 4) +} + +func growStack(n int) int { + var buf [128]int + if n == 0 { + return 0 + } + return buf[growStack(n-1)] +} + +func issue7978go() { + C.issue7978c((*C.uint32_t)(&issue7978sync)) + issue7978wait(7, 8) +} + +func test7978(t *testing.T) { + if runtime.Compiler == "gccgo" { + t.Skip("gccgo can not do stack traces of C code") + } + debug.SetTraceback("2") + issue7978sync = 0 + go issue7978go() + // test in c code, before callback + issue7978wait(0, 1) + issue7978check(t, "_Cfunc_issue7978c(", "", 1) + // test in go code, during callback + issue7978wait(2, 3) + issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3) + // test in c code, after callback + issue7978wait(4, 5) + issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1) + // test in go code, after return from cgo + issue7978wait(6, 7) + issue7978check(t, "test.issue7978go(", "", 3) + atomic.StoreUint32(&issue7978sync, 8) +} + +// issue 8331 part 2 + +var issue8331Var C.issue8331 + +// issue 20910 + +//export multi +func multi() (*C.char, C.int) { + return C.CString("multi"), 0 +} + +func test20910(t *testing.T) { + C.callMulti() +} + +// issue 28772 part 2 + +const issue28772Constant2 = C.issue28772Constant2 diff --git a/libgo/misc/cgo/test/twoargs.go b/libgo/misc/cgo/test/twoargs.go deleted file mode 100644 index ca0534c..0000000 --- a/libgo/misc/cgo/test/twoargs.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Crash from call with two arguments that need pointer checking. -// No runtime test; just make sure it compiles. - -package cgotest - -/* -static void twoargs1(void *p, int n) {} -static void *twoargs2() { return 0; } -static int twoargs3(void * p) { return 0; } -*/ -import "C" - -import "unsafe" - -func twoargsF() { - v := []string{} - C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v))) -} diff --git a/libgo/misc/cgo/testcarchive/carchive_test.go b/libgo/misc/cgo/testcarchive/carchive_test.go index 457ac0d..7051670 100644 --- a/libgo/misc/cgo/testcarchive/carchive_test.go +++ b/libgo/misc/cgo/testcarchive/carchive_test.go @@ -8,8 +8,10 @@ import ( "bufio" "bytes" "debug/elf" + "flag" "fmt" "io/ioutil" + "log" "os" "os/exec" "path/filepath" @@ -28,16 +30,47 @@ var bin []string // C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)). var cc []string -// An environment with GOPATH=$(pwd). -var gopathEnv []string - // ".exe" on Windows. var exeSuffix string -var GOOS, GOARCH string +var GOOS, GOARCH, GOPATH string var libgodir string -func init() { +func TestMain(m *testing.M) { + flag.Parse() + if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { + fmt.Printf("SKIP - short mode and $GO_BUILDER_NAME not set\n") + os.Exit(0) + } + log.SetFlags(log.Lshortfile) + os.Exit(testMain(m)) +} + +func testMain(m *testing.M) int { + // We need a writable GOPATH in which to run the tests. + // Construct one in a temporary directory. + var err error + GOPATH, err = ioutil.TempDir("", "carchive_test") + if err != nil { + log.Panic(err) + } + defer os.RemoveAll(GOPATH) + os.Setenv("GOPATH", GOPATH) + + // Copy testdata into GOPATH/src/testarchive, along with a go.mod file + // declaring the same path. + modRoot := filepath.Join(GOPATH, "src", "testcarchive") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := os.Chdir(modRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", modRoot) + if err := ioutil.WriteFile("go.mod", []byte("module testcarchive\n"), 0666); err != nil { + log.Panic(err) + } + GOOS = goEnv("GOOS") GOARCH = goEnv("GOARCH") bin = cmdToRun("./testp") @@ -83,50 +116,41 @@ func init() { // TODO(crawshaw): can we do better? cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...) } - libgodir = GOOS + "_" + GOARCH + if GOOS == "aix" { + // -Wl,-bnoobjreorder is mandatory to keep the same layout + // in .text section. + cc = append(cc, "-Wl,-bnoobjreorder") + } + libbase := GOOS + "_" + GOARCH if runtime.Compiler == "gccgo" { - libgodir = "gccgo_" + libgodir + "_fPIC" + libbase = "gccgo_" + libbase + "_fPIC" } else { switch GOOS { case "darwin": if GOARCH == "arm" || GOARCH == "arm64" { - libgodir += "_shared" + libbase += "_shared" } - case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": - libgodir += "_shared" + case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": + libbase += "_shared" } } - cc = append(cc, "-I", filepath.Join("pkg", libgodir)) - - // Build an environment with GOPATH=$(pwd) - env := os.Environ() - var n []string - for _, e := range env { - if !strings.HasPrefix(e, "GOPATH=") { - n = append(n, e) - } - } - dir, err := os.Getwd() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(2) - } - n = append(n, "GOPATH="+dir) - gopathEnv = n + libgodir = filepath.Join(GOPATH, "pkg", libbase, "testcarchive") + cc = append(cc, "-I", libgodir) if GOOS == "windows" { exeSuffix = ".exe" } + + return m.Run() } func goEnv(key string) string { out, err := exec.Command("go", "env", key).Output() if err != nil { - fmt.Fprintf(os.Stderr, "go env %s failed:\n%s\n", key, err) if ee, ok := err.(*exec.ExitError); ok { fmt.Fprintf(os.Stderr, "%s", ee.Stderr) } - os.Exit(2) + log.Panicf("go env %s failed:\n%s\n", key, err) } return strings.TrimSpace(string(out)) } @@ -143,7 +167,6 @@ func cmdToRun(name string) []string { func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { t.Helper() cmd := exec.Command(buildcmd[0], buildcmd[1:]...) - cmd.Env = gopathEnv t.Log(buildcmd) if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) @@ -204,7 +227,7 @@ func checkLineComments(t *testing.T, hdrname string) { } func TestInstall(t *testing.T) { - defer os.RemoveAll("pkg") + defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) libgoa := "libgo.a" if runtime.Compiler == "gccgo" { @@ -212,17 +235,17 @@ func TestInstall(t *testing.T) { } testInstall(t, "./testp1"+exeSuffix, - filepath.Join("pkg", libgodir, libgoa), - filepath.Join("pkg", libgodir, "libgo.h"), - "go", "install", "-i", "-buildmode=c-archive", "libgo") + filepath.Join(libgodir, libgoa), + filepath.Join(libgodir, "libgo.h"), + "go", "install", "-i", "-buildmode=c-archive", "./libgo") // Test building libgo other than installing it. // Header files are now present. testInstall(t, "./testp2"+exeSuffix, "libgo.a", "libgo.h", - "go", "build", "-buildmode=c-archive", filepath.Join("src", "libgo", "libgo.go")) + "go", "build", "-buildmode=c-archive", filepath.Join(".", "libgo", "libgo.go")) testInstall(t, "./testp3"+exeSuffix, "libgo.a", "libgo.h", - "go", "build", "-buildmode=c-archive", "-o", "libgo.a", "libgo") + "go", "build", "-buildmode=c-archive", "-o", "libgo.a", "./libgo") } func TestEarlySignalHandler(t *testing.T) { @@ -240,11 +263,10 @@ func TestEarlySignalHandler(t *testing.T) { os.Remove("libgo2.a") os.Remove("libgo2.h") os.Remove("testp") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -273,11 +295,10 @@ func TestSignalForwarding(t *testing.T) { os.Remove("libgo2.a") os.Remove("libgo2.h") os.Remove("testp") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -308,8 +329,10 @@ func TestSignalForwarding(t *testing.T) { } func TestSignalForwardingExternal(t *testing.T) { - if GOOS == "freebsd" { + if GOOS == "freebsd" || GOOS == "aix" { t.Skipf("skipping on %s/%s; signal always goes to the Go runtime", GOOS, GOARCH) + } else if GOOS == "darwin" && GOARCH == "amd64" { + t.Skipf("skipping on %s/%s: runtime does not permit SI_USER SIGSEGV", GOOS, GOARCH) } checkSignalForwardingTest(t) @@ -317,11 +340,10 @@ func TestSignalForwardingExternal(t *testing.T) { os.Remove("libgo2.a") os.Remove("libgo2.h") os.Remove("testp") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "libgo2") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -433,11 +455,10 @@ func TestOsSignal(t *testing.T) { os.Remove("libgo3.a") os.Remove("libgo3.h") os.Remove("testp") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "libgo3") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -469,11 +490,10 @@ func TestSigaltstack(t *testing.T) { os.Remove("libgo4.a") os.Remove("libgo4.h") os.Remove("testp") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "libgo4") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -511,13 +531,16 @@ func TestExtar(t *testing.T) { if runtime.Compiler == "gccgo" { t.Skip("skipping -extar test when using gccgo") } + if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") { + t.Skip("shell scripts are not executable on iOS hosts") + } defer func() { os.Remove("libgo4.a") os.Remove("libgo4.h") os.Remove("testar") os.Remove("testar.ran") - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() os.Remove("testar") @@ -530,8 +553,7 @@ func TestExtar(t *testing.T) { t.Fatal(err) } - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "libgo4") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-ldflags=-extar="+filepath.Join(dir, "testar"), "-o", "libgo4.a", "./libgo4") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -555,11 +577,10 @@ func TestPIE(t *testing.T) { defer func() { os.Remove("testp" + exeSuffix) - os.RemoveAll("pkg") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) }() - cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "libgo") - cmd.Env = gopathEnv + cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "./libgo") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -570,7 +591,7 @@ func TestPIE(t *testing.T) { libgoa = "liblibgo.a" } - ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, libgoa)) + ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join(libgodir, libgoa)) if runtime.Compiler == "gccgo" { ccArgs = append(ccArgs, "-lgo") } @@ -589,13 +610,15 @@ func TestPIE(t *testing.T) { t.Fatal(err) } - f, err := elf.Open("testp" + exeSuffix) - if err != nil { - t.Fatal("elf.Open failed: ", err) - } - defer f.Close() - if hasDynTag(t, f, elf.DT_TEXTREL) { - t.Errorf("%s has DT_TEXTREL flag", "testp"+exeSuffix) + if GOOS != "aix" { + f, err := elf.Open("testp" + exeSuffix) + if err != nil { + t.Fatal("elf.Open failed: ", err) + } + defer f.Close() + if hasDynTag(t, f, elf.DT_TEXTREL) { + t.Errorf("%s has DT_TEXTREL flag", "testp"+exeSuffix) + } } } @@ -643,8 +666,7 @@ func TestSIGPROF(t *testing.T) { os.Remove("libgo6.h") }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "libgo6") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -683,8 +705,7 @@ func TestCompileWithoutShared(t *testing.T) { os.Remove("libgo2.h") }() - cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "libgo2") - cmd.Env = gopathEnv + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2") t.Log(cmd.Args) out, err := cmd.CombinedOutput() t.Logf("%s", out) @@ -732,15 +753,14 @@ func TestCompileWithoutShared(t *testing.T) { // Test that installing a second time recreates the header files. func TestCachedInstall(t *testing.T) { - defer os.RemoveAll("pkg") + defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) - h1 := filepath.Join("pkg", libgodir, "libgo.h") - h2 := filepath.Join("pkg", libgodir, "p.h") + h1 := filepath.Join(libgodir, "libgo.h") + h2 := filepath.Join(libgodir, "p.h") - buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"} + buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "./libgo"} cmd := exec.Command(buildcmd[0], buildcmd[1:]...) - cmd.Env = gopathEnv t.Log(buildcmd) if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) @@ -762,7 +782,6 @@ func TestCachedInstall(t *testing.T) { } cmd = exec.Command(buildcmd[0], buildcmd[1:]...) - cmd.Env = gopathEnv t.Log(buildcmd) if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) diff --git a/libgo/misc/cgo/testcarchive/main.c b/libgo/misc/cgo/testcarchive/main.c deleted file mode 100644 index 163b539..0000000 --- a/libgo/misc/cgo/testcarchive/main.c +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include -#include - -#include "p.h" -#include "libgo.h" - -extern int install_handler(); -extern int check_handler(); - -int main(void) { - int32_t res; - - int r1 = install_handler(); - if (r1!=0) { - return r1; - } - - if (!DidInitRun()) { - fprintf(stderr, "ERROR: buildmode=c-archive init should run\n"); - return 2; - } - - if (DidMainRun()) { - fprintf(stderr, "ERROR: buildmode=c-archive should not run main\n"); - return 2; - } - - int r2 = check_handler(); - if (r2!=0) { - return r2; - } - - res = FromPkg(); - if (res != 1024) { - fprintf(stderr, "ERROR: FromPkg()=%d, want 1024\n", res); - return 2; - } - - CheckArgs(); - - fprintf(stderr, "PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main2.c b/libgo/misc/cgo/testcarchive/main2.c deleted file mode 100644 index 769cd49..0000000 --- a/libgo/misc/cgo/testcarchive/main2.c +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test installing a signal handler before the Go code starts. -// This is a lot like misc/cgo/testcshared/main4.c. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libgo2.h" - -static void die(const char* msg) { - perror(msg); - exit(EXIT_FAILURE); -} - -static volatile sig_atomic_t sigioSeen; -static volatile sig_atomic_t sigpipeSeen; - -// Use up some stack space. -static void recur(int i, char *p) { - char a[1024]; - - *p = '\0'; - if (i > 0) { - recur(i - 1, a); - } -} - -static void pipeHandler(int signo, siginfo_t* info, void* ctxt) { - sigpipeSeen = 1; -} - -// Signal handler that uses up more stack space than a goroutine will have. -static void ioHandler(int signo, siginfo_t* info, void* ctxt) { - char a[1024]; - - recur(4, a); - sigioSeen = 1; -} - -static jmp_buf jmp; -static char* nullPointer; - -// An arbitrary function which requires proper stack alignment; see -// http://golang.org/issue/17641. -static void callWithVarargs(void* dummy, ...) { - va_list args; - va_start(args, dummy); - va_end(args); -} - -// Signal handler for SIGSEGV on a C thread. -static void segvHandler(int signo, siginfo_t* info, void* ctxt) { - sigset_t mask; - int i; - - // Call an arbitrary function that requires the stack to be properly aligned. - callWithVarargs("dummy arg", 3.1415); - - if (sigemptyset(&mask) < 0) { - die("sigemptyset"); - } - if (sigaddset(&mask, SIGSEGV) < 0) { - die("sigaddset"); - } - i = sigprocmask(SIG_UNBLOCK, &mask, NULL); - if (i != 0) { - fprintf(stderr, "sigprocmask: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - // Don't try this at home. - longjmp(jmp, signo); - - // We should never get here. - abort(); -} - -// Set up the signal handlers in a high priority constructor, -// so that they are installed before the Go code starts. - -static void init(void) __attribute__ ((constructor (200))); - -static void init() { - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = ioHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGIO, &sa, NULL) < 0) { - die("sigaction"); - } - - sa.sa_sigaction = segvHandler; - if (sigaction(SIGSEGV, &sa, NULL) < 0 || sigaction(SIGBUS, &sa, NULL) < 0) { - die("sigaction"); - } - - sa.sa_sigaction = pipeHandler; - if (sigaction(SIGPIPE, &sa, NULL) < 0) { - die("sigaction"); - } -} - -int main(int argc, char** argv) { - int verbose; - sigset_t mask; - int i; - struct timespec ts; - - verbose = argc > 1; - setvbuf(stdout, NULL, _IONBF, 0); - - // Call setsid so that we can use kill(0, SIGIO) below. - // Don't check the return value so that this works both from - // a job control shell and from a shell script. - setsid(); - - if (verbose) { - printf("calling RunGoroutines\n"); - } - - RunGoroutines(); - - // Block SIGIO in this thread to make it more likely that it - // will be delivered to a goroutine. - - if (verbose) { - printf("calling pthread_sigmask\n"); - } - - if (sigemptyset(&mask) < 0) { - die("sigemptyset"); - } - if (sigaddset(&mask, SIGIO) < 0) { - die("sigaddset"); - } - i = pthread_sigmask(SIG_BLOCK, &mask, NULL); - if (i != 0) { - fprintf(stderr, "pthread_sigmask: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling kill\n"); - } - - if (kill(0, SIGIO) < 0) { - die("kill"); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for SIGIO\n"); - exit(EXIT_FAILURE); - } - } - - if (verbose) { - printf("provoking SIGPIPE\n"); - } - - GoRaiseSIGPIPE(); - - if (verbose) { - printf("waiting for sigpipeSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigpipeSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for SIGPIPE\n"); - exit(EXIT_FAILURE); - } - } - - if (verbose) { - printf("calling setjmp\n"); - } - - // Test that a SIGSEGV on this thread is delivered to us. - if (setjmp(jmp) == 0) { - if (verbose) { - printf("triggering SIGSEGV\n"); - } - - *nullPointer = '\0'; - - fprintf(stderr, "continued after address error\n"); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling TestSEGV\n"); - } - - TestSEGV(); - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main3.c b/libgo/misc/cgo/testcarchive/main3.c deleted file mode 100644 index 60a16cf..0000000 --- a/libgo/misc/cgo/testcarchive/main3.c +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test os/signal.Notify and os/signal.Reset. -// This is a lot like misc/cgo/testcshared/main5.c. - -#include -#include -#include -#include -#include -#include -#include - -#include "libgo3.h" - -static void die(const char* msg) { - perror(msg); - exit(EXIT_FAILURE); -} - -static volatile sig_atomic_t sigioSeen; - -static void ioHandler(int signo, siginfo_t* info, void* ctxt) { - sigioSeen = 1; -} - -// Set up the SIGPIPE signal handler in a high priority constructor, so -// that it is installed before the Go code starts. - -static void pipeHandler(int signo, siginfo_t* info, void* ctxt) { - const char *s = "unexpected SIGPIPE\n"; - write(2, s, strlen(s)); - exit(EXIT_FAILURE); -} - -static void init(void) __attribute__ ((constructor (200))); - -static void init() { - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = pipeHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGPIPE, &sa, NULL) < 0) { - die("sigaction"); - } -} - -int main(int argc, char** argv) { - int verbose; - struct sigaction sa; - int i; - struct timespec ts; - - verbose = argc > 2; - setvbuf(stdout, NULL, _IONBF, 0); - - if (verbose) { - printf("raising SIGPIPE\n"); - } - - // Test that the Go runtime handles SIGPIPE, even if we installed - // a non-default SIGPIPE handler before the runtime initializes. - ProvokeSIGPIPE(); - - if (verbose) { - printf("calling sigaction\n"); - } - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = ioHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGIO, &sa, NULL) < 0) { - die("sigaction"); - } - - // At this point there should not be a Go signal handler - // installed for SIGIO. - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - sigioSeen = 0; - - // Tell the Go code to catch SIGIO. - - if (verbose) { - printf("calling CatchSIGIO\n"); - } - - CatchSIGIO(); - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("calling SawSIGIO\n"); - } - - if (!SawSIGIO()) { - fprintf(stderr, "Go handler did not see SIGIO\n"); - exit(EXIT_FAILURE); - } - - if (sigioSeen != 0) { - fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n"); - exit(EXIT_FAILURE); - } - - // Tell the Go code to stop catching SIGIO. - - if (verbose) { - printf("calling ResetSIGIO\n"); - } - - ResetSIGIO(); - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("calling SawSIGIO\n"); - } - - if (SawSIGIO()) { - fprintf(stderr, "Go handler saw SIGIO after Reset\n"); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main4.c b/libgo/misc/cgo/testcarchive/main4.c deleted file mode 100644 index 4fd55e7..0000000 --- a/libgo/misc/cgo/testcarchive/main4.c +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test a C thread that calls sigaltstack and then calls Go code. - -#include -#include -#include -#include -#include -#include -#include - -#include "libgo4.h" - -static void die(const char* msg) { - perror(msg); - exit(EXIT_FAILURE); -} - -static int ok = 1; - -static void ioHandler(int signo, siginfo_t* info, void* ctxt) { -} - -// Set up the SIGIO signal handler in a high priority constructor, so -// that it is installed before the Go code starts. - -static void init(void) __attribute__ ((constructor (200))); - -static void init() { - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = ioHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO | SA_ONSTACK; - if (sigaction(SIGIO, &sa, NULL) < 0) { - die("sigaction"); - } -} - -// Test raising SIGIO on a C thread with an alternate signal stack -// when there is a Go signal handler for SIGIO. -static void* thread1(void* arg __attribute__ ((unused))) { - stack_t ss; - int i; - stack_t nss; - struct timespec ts; - - // Set up an alternate signal stack for this thread. - memset(&ss, 0, sizeof ss); - ss.ss_sp = malloc(SIGSTKSZ); - if (ss.ss_sp == NULL) { - die("malloc"); - } - ss.ss_flags = 0; - ss.ss_size = SIGSTKSZ; - if (sigaltstack(&ss, NULL) < 0) { - die("sigaltstack"); - } - - // Send ourselves a SIGIO. This will be caught by the Go - // signal handler which should forward to the C signal - // handler. - i = pthread_kill(pthread_self(), SIGIO); - if (i != 0) { - fprintf(stderr, "pthread_kill: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - // Wait until the signal has been delivered. - i = 0; - while (SIGIOCount() == 0) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - // We should still be on the same signal stack. - if (sigaltstack(NULL, &nss) < 0) { - die("sigaltstack check"); - } - if ((nss.ss_flags & SS_DISABLE) != 0) { - fprintf(stderr, "sigaltstack disabled on return from Go\n"); - ok = 0; - } else if (nss.ss_sp != ss.ss_sp) { - fprintf(stderr, "sigalstack changed on return from Go\n"); - ok = 0; - } - - return NULL; -} - -// Test calling a Go function to raise SIGIO on a C thread with an -// alternate signal stack when there is a Go signal handler for SIGIO. -static void* thread2(void* arg __attribute__ ((unused))) { - stack_t ss; - int i; - int oldcount; - pthread_t tid; - struct timespec ts; - stack_t nss; - - // Set up an alternate signal stack for this thread. - memset(&ss, 0, sizeof ss); - ss.ss_sp = malloc(SIGSTKSZ); - if (ss.ss_sp == NULL) { - die("malloc"); - } - ss.ss_flags = 0; - ss.ss_size = SIGSTKSZ; - if (sigaltstack(&ss, NULL) < 0) { - die("sigaltstack"); - } - - oldcount = SIGIOCount(); - - // Call a Go function that will call a C function to send us a - // SIGIO. - tid = pthread_self(); - GoRaiseSIGIO(&tid); - - // Wait until the signal has been delivered. - i = 0; - while (SIGIOCount() == oldcount) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - // We should still be on the same signal stack. - if (sigaltstack(NULL, &nss) < 0) { - die("sigaltstack check"); - } - if ((nss.ss_flags & SS_DISABLE) != 0) { - fprintf(stderr, "sigaltstack disabled on return from Go\n"); - ok = 0; - } else if (nss.ss_sp != ss.ss_sp) { - fprintf(stderr, "sigalstack changed on return from Go\n"); - ok = 0; - } - - return NULL; -} - -int main(int argc, char **argv) { - pthread_t tid; - int i; - - // Tell the Go library to start looking for SIGIO. - GoCatchSIGIO(); - - i = pthread_create(&tid, NULL, thread1, NULL); - if (i != 0) { - fprintf(stderr, "pthread_create: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - i = pthread_join(tid, NULL); - if (i != 0) { - fprintf(stderr, "pthread_join: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - i = pthread_create(&tid, NULL, thread2, NULL); - if (i != 0) { - fprintf(stderr, "pthread_create: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - i = pthread_join(tid, NULL); - if (i != 0) { - fprintf(stderr, "pthread_join: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - if (!ok) { - exit(EXIT_FAILURE); - } - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main5.c b/libgo/misc/cgo/testcarchive/main5.c deleted file mode 100644 index 897b70d..0000000 --- a/libgo/misc/cgo/testcarchive/main5.c +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test for verifying that the Go runtime properly forwards -// signals when non-Go signals are raised. - -#include -#include -#include -#include -#include -#include - -#include "libgo2.h" - -int main(int argc, char** argv) { - int verbose; - int test; - - if (argc < 2) { - printf("Missing argument\n"); - return 1; - } - - test = atoi(argv[1]); - - verbose = (argc > 2); - - if (verbose) { - printf("calling RunGoroutines\n"); - } - - Noop(); - - switch (test) { - case 1: { - if (verbose) { - printf("attempting segfault\n"); - } - - volatile int crash = *(int *) 0; - break; - } - - case 2: { - struct timeval tv; - - if (verbose) { - printf("attempting external signal test\n"); - } - - fprintf(stderr, "OK\n"); - fflush(stderr); - - // The program should be interrupted before - // this sleep finishes. We use select rather - // than sleep because in older versions of - // glibc the sleep function does some signal - // fiddling to handle SIGCHLD. If this - // program is fiddling signals just when the - // test program sends the signal, the signal - // may be delivered to a Go thread which will - // break this test. - tv.tv_sec = 60; - tv.tv_usec = 0; - select(0, NULL, NULL, NULL, &tv); - - break; - } - case 3: { - if (verbose) { - printf("attempting SIGPIPE\n"); - } - - int fd[2]; - if (pipe(fd) != 0) { - printf("pipe(2) failed\n"); - return 0; - } - // Close the reading end. - close(fd[0]); - // Expect that write(2) fails (EPIPE) - if (write(fd[1], "some data", 9) != -1) { - printf("write(2) unexpectedly succeeded\n"); - return 0; - } - printf("did not receieve SIGPIPE\n"); - return 0; - } - default: - printf("Unknown test: %d\n", test); - return 0; - } - - printf("FAIL\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main6.c b/libgo/misc/cgo/testcarchive/main6.c deleted file mode 100644 index 2745eb9..0000000 --- a/libgo/misc/cgo/testcarchive/main6.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that using the Go profiler in a C program does not crash. - -#include -#include - -#include "libgo6.h" - -int main(int argc, char **argv) { - struct timeval tvstart, tvnow; - int diff; - - gettimeofday(&tvstart, NULL); - - go_start_profile(); - - // Busy wait so we have something to profile. - // If we just sleep the profiling signal will never fire. - while (1) { - gettimeofday(&tvnow, NULL); - diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec); - - // Profile frequency is 100Hz so we should definitely - // get a signal in 50 milliseconds. - if (diff > 50 * 1000) - break; - } - - go_stop_profile(); - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/main_unix.c b/libgo/misc/cgo/testcarchive/main_unix.c deleted file mode 100644 index b23ac1c..0000000 --- a/libgo/misc/cgo/testcarchive/main_unix.c +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include -#include -#include -#include - -struct sigaction sa; -struct sigaction osa; - -static void (*oldHandler)(int, siginfo_t*, void*); - -static void handler(int signo, siginfo_t* info, void* ctxt) { - if (oldHandler) { - oldHandler(signo, info, ctxt); - } -} - -int install_handler() { - // Install our own signal handler. - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK | SA_SIGINFO; - memset(&osa, 0, sizeof osa); - sigemptyset(&osa.sa_mask); - if (sigaction(SIGSEGV, &sa, &osa) < 0) { - perror("sigaction"); - return 2; - } - if (osa.sa_handler == SIG_DFL) { - fprintf(stderr, "Go runtime did not install signal handler\n"); - return 2; - } - // gccgo does not set SA_ONSTACK for SIGSEGV. - if (getenv("GCCGO") == "" && (osa.sa_flags&SA_ONSTACK) == 0) { - fprintf(stderr, "Go runtime did not install signal handler\n"); - return 2; - } - oldHandler = osa.sa_sigaction; - - return 0; -} - -int check_handler() { - if (sigaction(SIGSEGV, NULL, &sa) < 0) { - perror("sigaction check"); - return 2; - } - if (sa.sa_sigaction != handler) { - fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler); - return 2; - } - return 0; -} - diff --git a/libgo/misc/cgo/testcarchive/main_windows.c b/libgo/misc/cgo/testcarchive/main_windows.c deleted file mode 100644 index eded8af..0000000 --- a/libgo/misc/cgo/testcarchive/main_windows.c +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Dummy implementations for Windows, because Windows doesn't - * support Unix-style signal handling. - */ - -int install_handler() { - return 0; -} - - -int check_handler() { - return 0; -} diff --git a/libgo/misc/cgo/testcarchive/overlaydir_test.go b/libgo/misc/cgo/testcarchive/overlaydir_test.go new file mode 100644 index 0000000..68878e4 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package carchive_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testcarchive/src/libgo/libgo.go b/libgo/misc/cgo/testcarchive/src/libgo/libgo.go deleted file mode 100644 index 45958a5..0000000 --- a/libgo/misc/cgo/testcarchive/src/libgo/libgo.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "os" - "syscall" - "time" - - _ "p" -) - -import "C" - -var initCh = make(chan int, 1) -var ranMain bool - -func init() { - // emulate an exceedingly slow package initialization function - time.Sleep(100 * time.Millisecond) - initCh <- 42 -} - -func main() { ranMain = true } - -//export DidInitRun -func DidInitRun() bool { - select { - case x := <-initCh: - if x != 42 { - // Just in case initCh was not correctly made. - println("want init value of 42, got: ", x) - syscall.Exit(2) - } - return true - default: - return false - } -} - -//export DidMainRun -func DidMainRun() bool { return ranMain } - -//export CheckArgs -func CheckArgs() { - if len(os.Args) != 3 || os.Args[1] != "arg1" || os.Args[2] != "arg2" { - fmt.Printf("CheckArgs: want [_, arg1, arg2], got: %v\n", os.Args) - os.Exit(2) - } -} diff --git a/libgo/misc/cgo/testcarchive/src/libgo2/libgo2.go b/libgo/misc/cgo/testcarchive/src/libgo2/libgo2.go deleted file mode 100644 index 19c8e1a..0000000 --- a/libgo/misc/cgo/testcarchive/src/libgo2/libgo2.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#include -#include -#include -#include - -// Raise SIGPIPE. -static void CRaiseSIGPIPE() { - int fds[2]; - - if (pipe(fds) == -1) { - perror("pipe"); - exit(EXIT_FAILURE); - } - // Close the reader end - close(fds[0]); - // Write to the writer end to provoke a SIGPIPE - if (write(fds[1], "some data", 9) != -1) { - fprintf(stderr, "write to a closed pipe succeeded\n"); - exit(EXIT_FAILURE); - } - close(fds[1]); -} -*/ -import "C" - -import ( - "fmt" - "os" - "runtime" -) - -// RunGoroutines starts some goroutines that don't do anything. -// The idea is to get some threads going, so that a signal will be delivered -// to a thread started by Go. -//export RunGoroutines -func RunGoroutines() { - for i := 0; i < 4; i++ { - go func() { - runtime.LockOSThread() - select {} - }() - } -} - -var P *byte - -// TestSEGV makes sure that an invalid address turns into a run-time Go panic. -//export TestSEGV -func TestSEGV() { - defer func() { - if recover() == nil { - fmt.Fprintln(os.Stderr, "no panic from segv") - os.Exit(1) - } - }() - *P = 0 - fmt.Fprintln(os.Stderr, "continued after segv") - os.Exit(1) -} - -// Noop ensures that the Go runtime is initialized. -//export Noop -func Noop() { -} - -// Raise SIGPIPE. -//export GoRaiseSIGPIPE -func GoRaiseSIGPIPE() { - C.CRaiseSIGPIPE() -} - -func main() { -} diff --git a/libgo/misc/cgo/testcarchive/src/libgo3/libgo3.go b/libgo/misc/cgo/testcarchive/src/libgo3/libgo3.go deleted file mode 100644 index 3725f7a..0000000 --- a/libgo/misc/cgo/testcarchive/src/libgo3/libgo3.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -import ( - "os" - "os/signal" - "syscall" - "time" -) - -// The channel used to read SIGIO signals. -var sigioChan chan os.Signal - -// CatchSIGIO starts catching SIGIO signals. -//export CatchSIGIO -func CatchSIGIO() { - sigioChan = make(chan os.Signal, 1) - signal.Notify(sigioChan, syscall.SIGIO) -} - -// ResetSIGIO stops catching SIGIO signals. -//export ResetSIGIO -func ResetSIGIO() { - signal.Reset(syscall.SIGIO) -} - -// SawSIGIO reports whether we saw a SIGIO. -//export SawSIGIO -func SawSIGIO() C.int { - select { - case <-sigioChan: - return 1 - case <-time.After(5 * time.Second): - return 0 - } -} - -// ProvokeSIGPIPE provokes a kernel-initiated SIGPIPE. -//export ProvokeSIGPIPE -func ProvokeSIGPIPE() { - r, w, err := os.Pipe() - if err != nil { - panic(err) - } - r.Close() - defer w.Close() - w.Write([]byte("some data")) -} - -func main() { -} diff --git a/libgo/misc/cgo/testcarchive/src/libgo4/libgo4.go b/libgo/misc/cgo/testcarchive/src/libgo4/libgo4.go deleted file mode 100644 index 8cc1895..0000000 --- a/libgo/misc/cgo/testcarchive/src/libgo4/libgo4.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#include -#include - -// Raise SIGIO. -static void CRaiseSIGIO(pthread_t* p) { - pthread_kill(*p, SIGIO); -} -*/ -import "C" - -import ( - "os" - "os/signal" - "sync/atomic" - "syscall" -) - -var sigioCount int32 - -// Catch SIGIO. -//export GoCatchSIGIO -func GoCatchSIGIO() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGIO) - go func() { - for range c { - atomic.AddInt32(&sigioCount, 1) - } - }() -} - -// Raise SIGIO. -//export GoRaiseSIGIO -func GoRaiseSIGIO(p *C.pthread_t) { - C.CRaiseSIGIO(p) -} - -// Return the number of SIGIO signals seen. -//export SIGIOCount -func SIGIOCount() C.int { - return C.int(atomic.LoadInt32(&sigioCount)) -} - -func main() { -} diff --git a/libgo/misc/cgo/testcarchive/src/libgo6/sigprof.go b/libgo/misc/cgo/testcarchive/src/libgo6/sigprof.go deleted file mode 100644 index 4cb05dc..0000000 --- a/libgo/misc/cgo/testcarchive/src/libgo6/sigprof.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "io/ioutil" - "runtime/pprof" -) - -import "C" - -//export go_start_profile -func go_start_profile() { - pprof.StartCPUProfile(ioutil.Discard) -} - -//export go_stop_profile -func go_stop_profile() { - pprof.StopCPUProfile() -} - -func main() { -} diff --git a/libgo/misc/cgo/testcarchive/src/p/p.go b/libgo/misc/cgo/testcarchive/src/p/p.go deleted file mode 100644 index 82b445c..0000000 --- a/libgo/misc/cgo/testcarchive/src/p/p.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package p - -import "C" - -//export FromPkg -func FromPkg() int32 { return 1024 } diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo/libgo.go b/libgo/misc/cgo/testcarchive/testdata/libgo/libgo.go new file mode 100644 index 0000000..37b30c1 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo/libgo.go @@ -0,0 +1,53 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "os" + "syscall" + "time" + + _ "testcarchive/p" +) + +import "C" + +var initCh = make(chan int, 1) +var ranMain bool + +func init() { + // emulate an exceedingly slow package initialization function + time.Sleep(100 * time.Millisecond) + initCh <- 42 +} + +func main() { ranMain = true } + +//export DidInitRun +func DidInitRun() bool { + select { + case x := <-initCh: + if x != 42 { + // Just in case initCh was not correctly made. + println("want init value of 42, got: ", x) + syscall.Exit(2) + } + return true + default: + return false + } +} + +//export DidMainRun +func DidMainRun() bool { return ranMain } + +//export CheckArgs +func CheckArgs() { + if len(os.Args) != 3 || os.Args[1] != "arg1" || os.Args[2] != "arg2" { + fmt.Printf("CheckArgs: want [_, arg1, arg2], got: %v\n", os.Args) + os.Exit(2) + } +} diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo2/libgo2.go b/libgo/misc/cgo/testcarchive/testdata/libgo2/libgo2.go new file mode 100644 index 0000000..19c8e1a --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo2/libgo2.go @@ -0,0 +1,80 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include +#include +#include +#include + +// Raise SIGPIPE. +static void CRaiseSIGPIPE() { + int fds[2]; + + if (pipe(fds) == -1) { + perror("pipe"); + exit(EXIT_FAILURE); + } + // Close the reader end + close(fds[0]); + // Write to the writer end to provoke a SIGPIPE + if (write(fds[1], "some data", 9) != -1) { + fprintf(stderr, "write to a closed pipe succeeded\n"); + exit(EXIT_FAILURE); + } + close(fds[1]); +} +*/ +import "C" + +import ( + "fmt" + "os" + "runtime" +) + +// RunGoroutines starts some goroutines that don't do anything. +// The idea is to get some threads going, so that a signal will be delivered +// to a thread started by Go. +//export RunGoroutines +func RunGoroutines() { + for i := 0; i < 4; i++ { + go func() { + runtime.LockOSThread() + select {} + }() + } +} + +var P *byte + +// TestSEGV makes sure that an invalid address turns into a run-time Go panic. +//export TestSEGV +func TestSEGV() { + defer func() { + if recover() == nil { + fmt.Fprintln(os.Stderr, "no panic from segv") + os.Exit(1) + } + }() + *P = 0 + fmt.Fprintln(os.Stderr, "continued after segv") + os.Exit(1) +} + +// Noop ensures that the Go runtime is initialized. +//export Noop +func Noop() { +} + +// Raise SIGPIPE. +//export GoRaiseSIGPIPE +func GoRaiseSIGPIPE() { + C.CRaiseSIGPIPE() +} + +func main() { +} diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo3/libgo3.go b/libgo/misc/cgo/testcarchive/testdata/libgo3/libgo3.go new file mode 100644 index 0000000..3725f7a --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo3/libgo3.go @@ -0,0 +1,56 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +import ( + "os" + "os/signal" + "syscall" + "time" +) + +// The channel used to read SIGIO signals. +var sigioChan chan os.Signal + +// CatchSIGIO starts catching SIGIO signals. +//export CatchSIGIO +func CatchSIGIO() { + sigioChan = make(chan os.Signal, 1) + signal.Notify(sigioChan, syscall.SIGIO) +} + +// ResetSIGIO stops catching SIGIO signals. +//export ResetSIGIO +func ResetSIGIO() { + signal.Reset(syscall.SIGIO) +} + +// SawSIGIO reports whether we saw a SIGIO. +//export SawSIGIO +func SawSIGIO() C.int { + select { + case <-sigioChan: + return 1 + case <-time.After(5 * time.Second): + return 0 + } +} + +// ProvokeSIGPIPE provokes a kernel-initiated SIGPIPE. +//export ProvokeSIGPIPE +func ProvokeSIGPIPE() { + r, w, err := os.Pipe() + if err != nil { + panic(err) + } + r.Close() + defer w.Close() + w.Write([]byte("some data")) +} + +func main() { +} diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo4/libgo4.go b/libgo/misc/cgo/testcarchive/testdata/libgo4/libgo4.go new file mode 100644 index 0000000..8cc1895 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo4/libgo4.go @@ -0,0 +1,52 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include +#include + +// Raise SIGIO. +static void CRaiseSIGIO(pthread_t* p) { + pthread_kill(*p, SIGIO); +} +*/ +import "C" + +import ( + "os" + "os/signal" + "sync/atomic" + "syscall" +) + +var sigioCount int32 + +// Catch SIGIO. +//export GoCatchSIGIO +func GoCatchSIGIO() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGIO) + go func() { + for range c { + atomic.AddInt32(&sigioCount, 1) + } + }() +} + +// Raise SIGIO. +//export GoRaiseSIGIO +func GoRaiseSIGIO(p *C.pthread_t) { + C.CRaiseSIGIO(p) +} + +// Return the number of SIGIO signals seen. +//export SIGIOCount +func SIGIOCount() C.int { + return C.int(atomic.LoadInt32(&sigioCount)) +} + +func main() { +} diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo6/sigprof.go b/libgo/misc/cgo/testcarchive/testdata/libgo6/sigprof.go new file mode 100644 index 0000000..4cb05dc --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo6/sigprof.go @@ -0,0 +1,25 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "io/ioutil" + "runtime/pprof" +) + +import "C" + +//export go_start_profile +func go_start_profile() { + pprof.StartCPUProfile(ioutil.Discard) +} + +//export go_stop_profile +func go_stop_profile() { + pprof.StopCPUProfile() +} + +func main() { +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main.c b/libgo/misc/cgo/testcarchive/testdata/main.c new file mode 100644 index 0000000..163b539 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main.c @@ -0,0 +1,48 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include + +#include "p.h" +#include "libgo.h" + +extern int install_handler(); +extern int check_handler(); + +int main(void) { + int32_t res; + + int r1 = install_handler(); + if (r1!=0) { + return r1; + } + + if (!DidInitRun()) { + fprintf(stderr, "ERROR: buildmode=c-archive init should run\n"); + return 2; + } + + if (DidMainRun()) { + fprintf(stderr, "ERROR: buildmode=c-archive should not run main\n"); + return 2; + } + + int r2 = check_handler(); + if (r2!=0) { + return r2; + } + + res = FromPkg(); + if (res != 1024) { + fprintf(stderr, "ERROR: FromPkg()=%d, want 1024\n", res); + return 2; + } + + CheckArgs(); + + fprintf(stderr, "PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main2.c b/libgo/misc/cgo/testcarchive/testdata/main2.c new file mode 100644 index 0000000..769cd49 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main2.c @@ -0,0 +1,232 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test installing a signal handler before the Go code starts. +// This is a lot like misc/cgo/testcshared/main4.c. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libgo2.h" + +static void die(const char* msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +static volatile sig_atomic_t sigioSeen; +static volatile sig_atomic_t sigpipeSeen; + +// Use up some stack space. +static void recur(int i, char *p) { + char a[1024]; + + *p = '\0'; + if (i > 0) { + recur(i - 1, a); + } +} + +static void pipeHandler(int signo, siginfo_t* info, void* ctxt) { + sigpipeSeen = 1; +} + +// Signal handler that uses up more stack space than a goroutine will have. +static void ioHandler(int signo, siginfo_t* info, void* ctxt) { + char a[1024]; + + recur(4, a); + sigioSeen = 1; +} + +static jmp_buf jmp; +static char* nullPointer; + +// An arbitrary function which requires proper stack alignment; see +// http://golang.org/issue/17641. +static void callWithVarargs(void* dummy, ...) { + va_list args; + va_start(args, dummy); + va_end(args); +} + +// Signal handler for SIGSEGV on a C thread. +static void segvHandler(int signo, siginfo_t* info, void* ctxt) { + sigset_t mask; + int i; + + // Call an arbitrary function that requires the stack to be properly aligned. + callWithVarargs("dummy arg", 3.1415); + + if (sigemptyset(&mask) < 0) { + die("sigemptyset"); + } + if (sigaddset(&mask, SIGSEGV) < 0) { + die("sigaddset"); + } + i = sigprocmask(SIG_UNBLOCK, &mask, NULL); + if (i != 0) { + fprintf(stderr, "sigprocmask: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + // Don't try this at home. + longjmp(jmp, signo); + + // We should never get here. + abort(); +} + +// Set up the signal handlers in a high priority constructor, +// so that they are installed before the Go code starts. + +static void init(void) __attribute__ ((constructor (200))); + +static void init() { + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = ioHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGIO, &sa, NULL) < 0) { + die("sigaction"); + } + + sa.sa_sigaction = segvHandler; + if (sigaction(SIGSEGV, &sa, NULL) < 0 || sigaction(SIGBUS, &sa, NULL) < 0) { + die("sigaction"); + } + + sa.sa_sigaction = pipeHandler; + if (sigaction(SIGPIPE, &sa, NULL) < 0) { + die("sigaction"); + } +} + +int main(int argc, char** argv) { + int verbose; + sigset_t mask; + int i; + struct timespec ts; + + verbose = argc > 1; + setvbuf(stdout, NULL, _IONBF, 0); + + // Call setsid so that we can use kill(0, SIGIO) below. + // Don't check the return value so that this works both from + // a job control shell and from a shell script. + setsid(); + + if (verbose) { + printf("calling RunGoroutines\n"); + } + + RunGoroutines(); + + // Block SIGIO in this thread to make it more likely that it + // will be delivered to a goroutine. + + if (verbose) { + printf("calling pthread_sigmask\n"); + } + + if (sigemptyset(&mask) < 0) { + die("sigemptyset"); + } + if (sigaddset(&mask, SIGIO) < 0) { + die("sigaddset"); + } + i = pthread_sigmask(SIG_BLOCK, &mask, NULL); + if (i != 0) { + fprintf(stderr, "pthread_sigmask: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling kill\n"); + } + + if (kill(0, SIGIO) < 0) { + die("kill"); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for SIGIO\n"); + exit(EXIT_FAILURE); + } + } + + if (verbose) { + printf("provoking SIGPIPE\n"); + } + + GoRaiseSIGPIPE(); + + if (verbose) { + printf("waiting for sigpipeSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigpipeSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for SIGPIPE\n"); + exit(EXIT_FAILURE); + } + } + + if (verbose) { + printf("calling setjmp\n"); + } + + // Test that a SIGSEGV on this thread is delivered to us. + if (setjmp(jmp) == 0) { + if (verbose) { + printf("triggering SIGSEGV\n"); + } + + *nullPointer = '\0'; + + fprintf(stderr, "continued after address error\n"); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling TestSEGV\n"); + } + + TestSEGV(); + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main3.c b/libgo/misc/cgo/testcarchive/testdata/main3.c new file mode 100644 index 0000000..60a16cf --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main3.c @@ -0,0 +1,189 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test os/signal.Notify and os/signal.Reset. +// This is a lot like misc/cgo/testcshared/main5.c. + +#include +#include +#include +#include +#include +#include +#include + +#include "libgo3.h" + +static void die(const char* msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +static volatile sig_atomic_t sigioSeen; + +static void ioHandler(int signo, siginfo_t* info, void* ctxt) { + sigioSeen = 1; +} + +// Set up the SIGPIPE signal handler in a high priority constructor, so +// that it is installed before the Go code starts. + +static void pipeHandler(int signo, siginfo_t* info, void* ctxt) { + const char *s = "unexpected SIGPIPE\n"; + write(2, s, strlen(s)); + exit(EXIT_FAILURE); +} + +static void init(void) __attribute__ ((constructor (200))); + +static void init() { + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = pipeHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGPIPE, &sa, NULL) < 0) { + die("sigaction"); + } +} + +int main(int argc, char** argv) { + int verbose; + struct sigaction sa; + int i; + struct timespec ts; + + verbose = argc > 2; + setvbuf(stdout, NULL, _IONBF, 0); + + if (verbose) { + printf("raising SIGPIPE\n"); + } + + // Test that the Go runtime handles SIGPIPE, even if we installed + // a non-default SIGPIPE handler before the runtime initializes. + ProvokeSIGPIPE(); + + if (verbose) { + printf("calling sigaction\n"); + } + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = ioHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGIO, &sa, NULL) < 0) { + die("sigaction"); + } + + // At this point there should not be a Go signal handler + // installed for SIGIO. + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + sigioSeen = 0; + + // Tell the Go code to catch SIGIO. + + if (verbose) { + printf("calling CatchSIGIO\n"); + } + + CatchSIGIO(); + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("calling SawSIGIO\n"); + } + + if (!SawSIGIO()) { + fprintf(stderr, "Go handler did not see SIGIO\n"); + exit(EXIT_FAILURE); + } + + if (sigioSeen != 0) { + fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n"); + exit(EXIT_FAILURE); + } + + // Tell the Go code to stop catching SIGIO. + + if (verbose) { + printf("calling ResetSIGIO\n"); + } + + ResetSIGIO(); + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("calling SawSIGIO\n"); + } + + if (SawSIGIO()) { + fprintf(stderr, "Go handler saw SIGIO after Reset\n"); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main4.c b/libgo/misc/cgo/testcarchive/testdata/main4.c new file mode 100644 index 0000000..04f7740 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main4.c @@ -0,0 +1,204 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test a C thread that calls sigaltstack and then calls Go code. + +#include +#include +#include +#include +#include +#include +#include + +#include "libgo4.h" + +#ifdef _AIX +// On AIX, CSIGSTKSZ is too small to handle Go sighandler. +#define CSIGSTKSZ 0x4000 +#else +#define CSIGSTKSZ SIGSTKSZ +#endif + +static void die(const char* msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +static int ok = 1; + +static void ioHandler(int signo, siginfo_t* info, void* ctxt) { +} + +// Set up the SIGIO signal handler in a high priority constructor, so +// that it is installed before the Go code starts. + +static void init(void) __attribute__ ((constructor (200))); + +static void init() { + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = ioHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + if (sigaction(SIGIO, &sa, NULL) < 0) { + die("sigaction"); + } +} + +// Test raising SIGIO on a C thread with an alternate signal stack +// when there is a Go signal handler for SIGIO. +static void* thread1(void* arg __attribute__ ((unused))) { + stack_t ss; + int i; + stack_t nss; + struct timespec ts; + + // Set up an alternate signal stack for this thread. + memset(&ss, 0, sizeof ss); + ss.ss_sp = malloc(CSIGSTKSZ); + if (ss.ss_sp == NULL) { + die("malloc"); + } + ss.ss_flags = 0; + ss.ss_size = CSIGSTKSZ; + if (sigaltstack(&ss, NULL) < 0) { + die("sigaltstack"); + } + + // Send ourselves a SIGIO. This will be caught by the Go + // signal handler which should forward to the C signal + // handler. + i = pthread_kill(pthread_self(), SIGIO); + if (i != 0) { + fprintf(stderr, "pthread_kill: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + // Wait until the signal has been delivered. + i = 0; + while (SIGIOCount() == 0) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + // We should still be on the same signal stack. + if (sigaltstack(NULL, &nss) < 0) { + die("sigaltstack check"); + } + if ((nss.ss_flags & SS_DISABLE) != 0) { + fprintf(stderr, "sigaltstack disabled on return from Go\n"); + ok = 0; + } else if (nss.ss_sp != ss.ss_sp) { + fprintf(stderr, "sigaltstack changed on return from Go\n"); + ok = 0; + } + + return NULL; +} + +// Test calling a Go function to raise SIGIO on a C thread with an +// alternate signal stack when there is a Go signal handler for SIGIO. +static void* thread2(void* arg __attribute__ ((unused))) { + stack_t ss; + int i; + int oldcount; + pthread_t tid; + struct timespec ts; + stack_t nss; + + // Set up an alternate signal stack for this thread. + memset(&ss, 0, sizeof ss); + ss.ss_sp = malloc(CSIGSTKSZ); + if (ss.ss_sp == NULL) { + die("malloc"); + } + ss.ss_flags = 0; + ss.ss_size = CSIGSTKSZ; + if (sigaltstack(&ss, NULL) < 0) { + die("sigaltstack"); + } + + oldcount = SIGIOCount(); + + // Call a Go function that will call a C function to send us a + // SIGIO. + tid = pthread_self(); + GoRaiseSIGIO(&tid); + + // Wait until the signal has been delivered. + i = 0; + while (SIGIOCount() == oldcount) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + // We should still be on the same signal stack. + if (sigaltstack(NULL, &nss) < 0) { + die("sigaltstack check"); + } + if ((nss.ss_flags & SS_DISABLE) != 0) { + fprintf(stderr, "sigaltstack disabled on return from Go\n"); + ok = 0; + } else if (nss.ss_sp != ss.ss_sp) { + fprintf(stderr, "sigaltstack changed on return from Go\n"); + ok = 0; + } + + return NULL; +} + +int main(int argc, char **argv) { + pthread_t tid; + int i; + + // Tell the Go library to start looking for SIGIO. + GoCatchSIGIO(); + + i = pthread_create(&tid, NULL, thread1, NULL); + if (i != 0) { + fprintf(stderr, "pthread_create: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + i = pthread_join(tid, NULL); + if (i != 0) { + fprintf(stderr, "pthread_join: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + i = pthread_create(&tid, NULL, thread2, NULL); + if (i != 0) { + fprintf(stderr, "pthread_create: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + i = pthread_join(tid, NULL); + if (i != 0) { + fprintf(stderr, "pthread_join: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + if (!ok) { + exit(EXIT_FAILURE); + } + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main5.c b/libgo/misc/cgo/testcarchive/testdata/main5.c new file mode 100644 index 0000000..d431ce0 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main5.c @@ -0,0 +1,100 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test for verifying that the Go runtime properly forwards +// signals when non-Go signals are raised. + +#include +#include +#include +#include +#include +#include + +#include "libgo2.h" + +int *nilp; + +int main(int argc, char** argv) { + int verbose; + int test; + + if (argc < 2) { + printf("Missing argument\n"); + return 1; + } + + test = atoi(argv[1]); + + verbose = (argc > 2); + + if (verbose) { + printf("calling RunGoroutines\n"); + } + + Noop(); + + switch (test) { + case 1: { + if (verbose) { + printf("attempting segfault\n"); + } + + *nilp = 0; + break; + } + + case 2: { + struct timeval tv; + + if (verbose) { + printf("attempting external signal test\n"); + } + + fprintf(stderr, "OK\n"); + fflush(stderr); + + // The program should be interrupted before + // this sleep finishes. We use select rather + // than sleep because in older versions of + // glibc the sleep function does some signal + // fiddling to handle SIGCHLD. If this + // program is fiddling signals just when the + // test program sends the signal, the signal + // may be delivered to a Go thread which will + // break this test. + tv.tv_sec = 60; + tv.tv_usec = 0; + select(0, NULL, NULL, NULL, &tv); + + break; + } + case 3: { + if (verbose) { + printf("attempting SIGPIPE\n"); + } + + int fd[2]; + if (pipe(fd) != 0) { + printf("pipe(2) failed\n"); + return 0; + } + // Close the reading end. + close(fd[0]); + // Expect that write(2) fails (EPIPE) + if (write(fd[1], "some data", 9) != -1) { + printf("write(2) unexpectedly succeeded\n"); + return 0; + } + printf("did not receive SIGPIPE\n"); + return 0; + } + default: + printf("Unknown test: %d\n", test); + return 0; + } + + printf("FAIL\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main6.c b/libgo/misc/cgo/testcarchive/testdata/main6.c new file mode 100644 index 0000000..2745eb9 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main6.c @@ -0,0 +1,34 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that using the Go profiler in a C program does not crash. + +#include +#include + +#include "libgo6.h" + +int main(int argc, char **argv) { + struct timeval tvstart, tvnow; + int diff; + + gettimeofday(&tvstart, NULL); + + go_start_profile(); + + // Busy wait so we have something to profile. + // If we just sleep the profiling signal will never fire. + while (1) { + gettimeofday(&tvnow, NULL); + diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec); + + // Profile frequency is 100Hz so we should definitely + // get a signal in 50 milliseconds. + if (diff > 50 * 1000) + break; + } + + go_stop_profile(); + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main_unix.c b/libgo/misc/cgo/testcarchive/testdata/main_unix.c new file mode 100644 index 0000000..b23ac1c --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main_unix.c @@ -0,0 +1,59 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include +#include +#include + +struct sigaction sa; +struct sigaction osa; + +static void (*oldHandler)(int, siginfo_t*, void*); + +static void handler(int signo, siginfo_t* info, void* ctxt) { + if (oldHandler) { + oldHandler(signo, info, ctxt); + } +} + +int install_handler() { + // Install our own signal handler. + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_ONSTACK | SA_SIGINFO; + memset(&osa, 0, sizeof osa); + sigemptyset(&osa.sa_mask); + if (sigaction(SIGSEGV, &sa, &osa) < 0) { + perror("sigaction"); + return 2; + } + if (osa.sa_handler == SIG_DFL) { + fprintf(stderr, "Go runtime did not install signal handler\n"); + return 2; + } + // gccgo does not set SA_ONSTACK for SIGSEGV. + if (getenv("GCCGO") == "" && (osa.sa_flags&SA_ONSTACK) == 0) { + fprintf(stderr, "Go runtime did not install signal handler\n"); + return 2; + } + oldHandler = osa.sa_sigaction; + + return 0; +} + +int check_handler() { + if (sigaction(SIGSEGV, NULL, &sa) < 0) { + perror("sigaction check"); + return 2; + } + if (sa.sa_sigaction != handler) { + fprintf(stderr, "ERROR: wrong signal handler: %p != %p\n", sa.sa_sigaction, handler); + return 2; + } + return 0; +} + diff --git a/libgo/misc/cgo/testcarchive/testdata/main_windows.c b/libgo/misc/cgo/testcarchive/testdata/main_windows.c new file mode 100644 index 0000000..eded8af --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main_windows.c @@ -0,0 +1,17 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + * Dummy implementations for Windows, because Windows doesn't + * support Unix-style signal handling. + */ + +int install_handler() { + return 0; +} + + +int check_handler() { + return 0; +} diff --git a/libgo/misc/cgo/testcarchive/testdata/p/p.go b/libgo/misc/cgo/testcarchive/testdata/p/p.go new file mode 100644 index 0000000..82b445c --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/p/p.go @@ -0,0 +1,10 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "C" + +//export FromPkg +func FromPkg() int32 { return 1024 } diff --git a/libgo/misc/cgo/testcshared/cshared_test.go b/libgo/misc/cgo/testcshared/cshared_test.go index e5b90ff..daef3a9 100644 --- a/libgo/misc/cgo/testcshared/cshared_test.go +++ b/libgo/misc/cgo/testcshared/cshared_test.go @@ -5,14 +5,16 @@ package cshared_test import ( + "bytes" "debug/elf" + "flag" "fmt" "io/ioutil" "log" "os" "os/exec" - "path" "path/filepath" + "runtime" "strings" "sync" "testing" @@ -22,9 +24,6 @@ import ( // C compiler with args (from $(go env CC) $(go env GOGCCFLAGS)). var cc []string -// An environment with GOPATH=$(pwd). -var gopathEnv []string - // ".exe" on Windows. var exeSuffix string @@ -33,6 +32,17 @@ var installdir, androiddir string var libSuffix, libgoname string func TestMain(m *testing.M) { + os.Exit(testMain(m)) +} + +func testMain(m *testing.M) int { + log.SetFlags(log.Lshortfile) + flag.Parse() + if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { + fmt.Printf("SKIP - short mode and $GO_BUILDER_NAME not set\n") + os.Exit(0) + } + GOOS = goEnv("GOOS") GOARCH = goEnv("GOARCH") GOROOT = goEnv("GOROOT") @@ -41,31 +51,17 @@ func TestMain(m *testing.M) { log.Fatalf("Unable able to find GOROOT at '%s'", GOROOT) } - // Directory where cgo headers and outputs will be installed. - // The installation directory format varies depending on the platform. - installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared", GOOS, GOARCH)) - switch GOOS { - case "darwin": - libSuffix = "dylib" - case "windows": - libSuffix = "dll" - default: - libSuffix = "so" - installdir = path.Join("pkg", fmt.Sprintf("%s_%s_testcshared_shared", GOOS, GOARCH)) - } - androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid()) - if GOOS == "android" { - args := append(adbCmd(), "shell", "mkdir", "-p", androiddir) + if runtime.GOOS != GOOS && GOOS == "android" { + args := append(adbCmd(), "exec-out", "mkdir", "-p", androiddir) cmd := exec.Command(args[0], args[1:]...) out, err := cmd.CombinedOutput() if err != nil { log.Fatalf("setupAndroid failed: %v\n%s\n", err, out) } + defer cleanupAndroid() } - libgoname = "libgo." + libSuffix - cc = []string{goEnv("CC")} out := goEnv("GOGCCFLAGS") @@ -115,39 +111,62 @@ func TestMain(m *testing.M) { if GOARCH == "arm" || GOARCH == "arm64" { libgodir += "_shared" } - case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": + case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": libgodir += "_shared" } cc = append(cc, "-I", filepath.Join("pkg", libgodir)) - // Build an environment with GOPATH=$(pwd) - dir, err := os.Getwd() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(2) - } - gopathEnv = append(os.Environ(), "GOPATH="+dir) - if GOOS == "windows" { exeSuffix = ".exe" } - st := m.Run() + // Copy testdata into GOPATH/src/testcshared, along with a go.mod file + // declaring the same path. - os.Remove(libgoname) - os.RemoveAll("pkg") - cleanupHeaders() - cleanupAndroid() + GOPATH, err := ioutil.TempDir("", "cshared_test") + if err != nil { + log.Panic(err) + } + defer os.RemoveAll(GOPATH) + os.Setenv("GOPATH", GOPATH) - os.Exit(st) + // Copy testdata into GOPATH/src/testarchive, along with a go.mod file + // declaring the same path. + modRoot := filepath.Join(GOPATH, "src", "testcshared") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := os.Chdir(modRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", modRoot) + if err := ioutil.WriteFile("go.mod", []byte("module testcshared\n"), 0666); err != nil { + log.Panic(err) + } + + // Directory where cgo headers and outputs will be installed. + // The installation directory format varies depending on the platform. + output, err := exec.Command("go", "list", + "-buildmode=c-shared", + "-installsuffix", "testcshared", + "-f", "{{.Target}}", + "./libgo").CombinedOutput() + if err != nil { + log.Panicf("go list failed: %v\n%s", err, output) + } + target := string(bytes.TrimSpace(output)) + libgoname = filepath.Base(target) + installdir = filepath.Dir(target) + libSuffix = strings.TrimPrefix(filepath.Ext(target), ".") + + return m.Run() } func goEnv(key string) string { out, err := exec.Command("go", "env", key).Output() if err != nil { - fmt.Fprintf(os.Stderr, "go env %s failed:\n%s", key, err) - fmt.Fprintf(os.Stderr, "%s", err.(*exec.ExitError).Stderr) - os.Exit(2) + log.Printf("go env %s failed:\n%s", key, err) + log.Panicf("%s", err.(*exec.ExitError).Stderr) } return strings.TrimSpace(string(out)) } @@ -165,7 +184,7 @@ func adbCmd() []string { } func adbPush(t *testing.T, filename string) { - if GOOS != "android" { + if runtime.GOOS == GOOS || GOOS != "android" { return } args := append(adbCmd(), "push", filename, fmt.Sprintf("%s/%s", androiddir, filename)) @@ -179,7 +198,7 @@ func adbRun(t *testing.T, env []string, adbargs ...string) string { if GOOS != "android" { t.Fatalf("trying to run adb command when operating system is not android.") } - args := append(adbCmd(), "shell") + args := append(adbCmd(), "exec-out") // Propagate LD_LIBRARY_PATH to the adb shell invocation. for _, e := range env { if strings.Index(e, "LD_LIBRARY_PATH=") != -1 { @@ -197,10 +216,12 @@ func adbRun(t *testing.T, env []string, adbargs ...string) string { return strings.Replace(string(out), "\r", "", -1) } -func run(t *testing.T, env []string, args ...string) string { +func run(t *testing.T, extraEnv []string, args ...string) string { t.Helper() cmd := exec.Command(args[0], args[1:]...) - cmd.Env = env + if len(extraEnv) > 0 { + cmd.Env = append(os.Environ(), extraEnv...) + } if GOOS != "windows" { // TestUnexportedSymbols relies on file descriptor 30 @@ -220,12 +241,12 @@ func run(t *testing.T, env []string, args ...string) string { return string(out) } -func runExe(t *testing.T, env []string, args ...string) string { +func runExe(t *testing.T, extraEnv []string, args ...string) string { t.Helper() - if GOOS == "android" { - return adbRun(t, env, args...) + if runtime.GOOS != GOOS && GOOS == "android" { + return adbRun(t, append(os.Environ(), extraEnv...), args...) } - return run(t, env, args...) + return run(t, extraEnv, args...) } func runCC(t *testing.T, args ...string) string { @@ -237,9 +258,8 @@ func runCC(t *testing.T, args ...string) string { func createHeaders() error { args := []string{"go", "install", "-i", "-buildmode=c-shared", - "-installsuffix", "testcshared", "libgo"} + "-installsuffix", "testcshared", "./libgo"} cmd := exec.Command(args[0], args[1:]...) - cmd.Env = gopathEnv out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out) @@ -248,15 +268,14 @@ func createHeaders() error { args = []string{"go", "build", "-buildmode=c-shared", "-installsuffix", "testcshared", "-o", libgoname, - filepath.Join("src", "libgo", "libgo.go")} + filepath.Join(".", "libgo", "libgo.go")} cmd = exec.Command(args[0], args[1:]...) - cmd.Env = gopathEnv out, err = cmd.CombinedOutput() if err != nil { return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out) } - if GOOS == "android" { + if runtime.GOOS != GOOS && GOOS == "android" { args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname)) cmd = exec.Command(args[0], args[1:]...) out, err = cmd.CombinedOutput() @@ -282,19 +301,15 @@ func createHeadersOnce(t *testing.T) { } } -func cleanupHeaders() { - os.Remove("libgo.h") -} - func cleanupAndroid() { if GOOS != "android" { return } - args := append(adbCmd(), "shell", "rm", "-rf", androiddir) + args := append(adbCmd(), "exec-out", "rm", "-rf", androiddir) cmd := exec.Command(args[0], args[1:]...) out, err := cmd.CombinedOutput() if err != nil { - log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out) + log.Panicf("cleanupAndroid failed: %v\n%s\n", err, out) } } @@ -312,7 +327,7 @@ func TestExportedSymbols(t *testing.T) { defer os.Remove(bin) - out := runExe(t, append(gopathEnv, "LD_LIBRARY_PATH=."), bin) + out := runExe(t, []string{"LD_LIBRARY_PATH=."}, bin) if strings.TrimSpace(out) != "PASS" { t.Error(out) } @@ -361,11 +376,11 @@ func TestUnexportedSymbols(t *testing.T) { libname := "libgo2." + libSuffix run(t, - gopathEnv, + nil, "go", "build", "-buildmode=c-shared", "-installsuffix", "testcshared", - "-o", libname, "libgo2", + "-o", libname, "./libgo2", ) adbPush(t, libname) @@ -380,7 +395,7 @@ func TestUnexportedSymbols(t *testing.T) { defer os.Remove(libname) defer os.Remove(bin) - out := runExe(t, append(gopathEnv, "LD_LIBRARY_PATH=."), bin) + out := runExe(t, []string{"LD_LIBRARY_PATH=."}, bin) if strings.TrimSpace(out) != "PASS" { t.Error(out) @@ -418,7 +433,7 @@ func TestMainExportedOnAndroid(t *testing.T) { func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) { libname := pkgname + "." + libSuffix run(t, - gopathEnv, + nil, "go", "build", "-buildmode=c-shared", "-installsuffix", "testcshared", @@ -451,7 +466,7 @@ func TestSignalHandlers(t *testing.T) { t.Logf("Skipping on %s", GOOS) return } - testSignalHandlers(t, "libgo4", "main4.c", "testp4") + testSignalHandlers(t, "./libgo4", "main4.c", "testp4") } // test5: test signal handlers with os/signal.Notify @@ -461,7 +476,7 @@ func TestSignalHandlersWithNotify(t *testing.T) { t.Logf("Skipping on %s", GOOS) return } - testSignalHandlers(t, "libgo5", "main5.c", "testp5") + testSignalHandlers(t, "./libgo5", "main5.c", "testp5") } func TestPIE(t *testing.T) { @@ -513,16 +528,18 @@ func TestCachedInstall(t *testing.T) { if err != nil { t.Fatal(err) } - // defer os.RemoveAll(tmpdir) + defer os.RemoveAll(tmpdir) - copyFile(t, filepath.Join(tmpdir, "src", "libgo", "libgo.go"), filepath.Join("src", "libgo", "libgo.go")) - copyFile(t, filepath.Join(tmpdir, "src", "p", "p.go"), filepath.Join("src", "p", "p.go")) + copyFile(t, filepath.Join(tmpdir, "src", "testcshared", "go.mod"), "go.mod") + copyFile(t, filepath.Join(tmpdir, "src", "testcshared", "libgo", "libgo.go"), filepath.Join("libgo", "libgo.go")) + copyFile(t, filepath.Join(tmpdir, "src", "testcshared", "p", "p.go"), filepath.Join("p", "p.go")) - env := append(os.Environ(), "GOPATH="+tmpdir) + env := append(os.Environ(), "GOPATH="+tmpdir, "GOBIN="+filepath.Join(tmpdir, "bin")) - buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "libgo"} + buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "./libgo"} cmd := exec.Command(buildcmd[0], buildcmd[1:]...) + cmd.Dir = filepath.Join(tmpdir, "src", "testcshared") cmd.Env = env t.Log(buildcmd) out, err := cmd.CombinedOutput() @@ -572,6 +589,7 @@ func TestCachedInstall(t *testing.T) { } cmd = exec.Command(buildcmd[0], buildcmd[1:]...) + cmd.Dir = filepath.Join(tmpdir, "src", "testcshared") cmd.Env = env t.Log(buildcmd) out, err = cmd.CombinedOutput() @@ -621,8 +639,8 @@ func TestGo2C2Go(t *testing.T) { } defer os.RemoveAll(tmpdir) - shlib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix) - run(t, gopathEnv, "go", "build", "-buildmode=c-shared", "-o", shlib, "go2c2go/go") + lib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix) + run(t, nil, "go", "build", "-buildmode=c-shared", "-o", lib, "./go2c2go/go") cgoCflags := os.Getenv("CGO_CFLAGS") if cgoCflags != "" { @@ -636,7 +654,7 @@ func TestGo2C2Go(t *testing.T) { } cgoLdflags += "-L" + tmpdir + " -ltestgo2c2go" - goenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "CGO_CFLAGS="+cgoCflags, "CGO_LDFLAGS="+cgoLdflags) + goenv := []string{"CGO_CFLAGS=" + cgoCflags, "CGO_LDFLAGS=" + cgoLdflags} ldLibPath := os.Getenv("LD_LIBRARY_PATH") if ldLibPath != "" { @@ -644,13 +662,13 @@ func TestGo2C2Go(t *testing.T) { } ldLibPath += tmpdir - runenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "LD_LIBRARY_PATH="+ldLibPath) + runenv := []string{"LD_LIBRARY_PATH=" + ldLibPath} bin := filepath.Join(tmpdir, "m1") + exeSuffix - run(t, goenv, "go", "build", "-o", bin, "go2c2go/m1") + run(t, goenv, "go", "build", "-o", bin, "./go2c2go/m1") runExe(t, runenv, bin) bin = filepath.Join(tmpdir, "m2") + exeSuffix - run(t, goenv, "go", "build", "-o", bin, "go2c2go/m2") + run(t, goenv, "go", "build", "-o", bin, "./go2c2go/m2") runExe(t, runenv, bin) } diff --git a/libgo/misc/cgo/testcshared/main0.c b/libgo/misc/cgo/testcshared/main0.c deleted file mode 100644 index 39ef7e3..0000000 --- a/libgo/misc/cgo/testcshared/main0.c +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include - -#include "p.h" -#include "libgo.h" - -// Tests libgo.so to export the following functions. -// int8_t DidInitRun(); -// int8_t DidMainRun(); -// int32_t FromPkg(); -// uint32_t Divu(uint32_t, uint32_t); -int main(void) { - int8_t ran_init = DidInitRun(); - if (!ran_init) { - fprintf(stderr, "ERROR: DidInitRun returned unexpected results: %d\n", - ran_init); - return 1; - } - int8_t ran_main = DidMainRun(); - if (ran_main) { - fprintf(stderr, "ERROR: DidMainRun returned unexpected results: %d\n", - ran_main); - return 1; - } - int32_t from_pkg = FromPkg(); - if (from_pkg != 1024) { - fprintf(stderr, "ERROR: FromPkg=%d, want %d\n", from_pkg, 1024); - return 1; - } - uint32_t divu = Divu(2264, 31); - if (divu != 73) { - fprintf(stderr, "ERROR: Divu(2264, 31)=%d, want %d\n", divu, 73); - return 1; - } - // test.bash looks for "PASS" to ensure this program has reached the end. - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/main1.c b/libgo/misc/cgo/testcshared/main1.c deleted file mode 100644 index 420dd1e..0000000 --- a/libgo/misc/cgo/testcshared/main1.c +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include -#include - -int check_int8(void* handle, const char* fname, int8_t want) { - int8_t (*fn)(); - fn = (int8_t (*)())dlsym(handle, fname); - if (!fn) { - fprintf(stderr, "ERROR: missing %s: %s\n", fname, dlerror()); - return 1; - } - signed char ret = fn(); - if (ret != want) { - fprintf(stderr, "ERROR: %s=%d, want %d\n", fname, ret, want); - return 1; - } - return 0; -} - -int check_int32(void* handle, const char* fname, int32_t want) { - int32_t (*fn)(); - fn = (int32_t (*)())dlsym(handle, fname); - if (!fn) { - fprintf(stderr, "ERROR: missing %s: %s\n", fname, dlerror()); - return 1; - } - int32_t ret = fn(); - if (ret != want) { - fprintf(stderr, "ERROR: %s=%d, want %d\n", fname, ret, want); - return 1; - } - return 0; -} - -// Tests libgo.so to export the following functions. -// int8_t DidInitRun() // returns true -// int8_t DidMainRun() // returns true -// int32_t FromPkg() // returns 1024 -int main(int argc, char** argv) { - void* handle = dlopen(argv[1], RTLD_LAZY | RTLD_GLOBAL); - if (!handle) { - fprintf(stderr, "ERROR: failed to open the shared library: %s\n", - dlerror()); - return 2; - } - - int ret = 0; - ret = check_int8(handle, "DidInitRun", 1); - if (ret != 0) { - return ret; - } - - ret = check_int8(handle, "DidMainRun", 0); - if (ret != 0) { - return ret; - } - - ret = check_int32(handle, "FromPkg", 1024); - if (ret != 0) { - return ret; - } - // test.bash looks for "PASS" to ensure this program has reached the end. - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/main2.c b/libgo/misc/cgo/testcshared/main2.c deleted file mode 100644 index f89bcca..0000000 --- a/libgo/misc/cgo/testcshared/main2.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include -#include -#include -#include -#include - -#define fd (30) - -// Tests libgo2.so, which does not export any functions. -// Read a string from the file descriptor and print it. -int main(void) { - int i; - ssize_t n; - char buf[20]; - struct timespec ts; - - // The descriptor will be initialized in a thread, so we have to - // give a chance to get opened. - for (i = 0; i < 200; i++) { - n = read(fd, buf, sizeof buf); - if (n >= 0) - break; - if (errno != EBADF && errno != EINVAL) { - fprintf(stderr, "BUG: read: %s\n", strerror(errno)); - return 2; - } - - // An EBADF error means that the shared library has not opened the - // descriptor yet. - ts.tv_sec = 0; - ts.tv_nsec = 10000000; - nanosleep(&ts, NULL); - } - - if (n < 0) { - fprintf(stderr, "BUG: failed to read any data from pipe\n"); - return 2; - } - - if (n == 0) { - fprintf(stderr, "BUG: unexpected EOF\n"); - return 2; - } - - if (n == sizeof buf) { - n--; - } - buf[n] = '\0'; - printf("%s\n", buf); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/main3.c b/libgo/misc/cgo/testcshared/main3.c deleted file mode 100644 index 49cc055..0000000 --- a/libgo/misc/cgo/testcshared/main3.c +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include -#include - -// Tests "main.main" is exported on android/arm, -// which golang.org/x/mobile/app depends on. -int main(int argc, char** argv) { - void* handle = dlopen(argv[1], RTLD_LAZY | RTLD_GLOBAL); - if (!handle) { - fprintf(stderr, "ERROR: failed to open the shared library: %s\n", - dlerror()); - return 2; - } - - uintptr_t main_fn = (uintptr_t)dlsym(handle, "main.main"); - if (!main_fn) { - fprintf(stderr, "ERROR: missing main.main: %s\n", dlerror()); - return 2; - } - - // TODO(hyangah): check that main.main can run. - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/main4.c b/libgo/misc/cgo/testcshared/main4.c deleted file mode 100644 index 355cdef..0000000 --- a/libgo/misc/cgo/testcshared/main4.c +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that a signal handler that uses up stack space does not crash -// if the signal is delivered to a thread running a goroutine. -// This is a lot like misc/cgo/testcarchive/main2.c. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void die(const char* msg) { - perror(msg); - exit(EXIT_FAILURE); -} - -static volatile sig_atomic_t sigioSeen; - -// Use up some stack space. -static void recur(int i, char *p) { - char a[1024]; - - *p = '\0'; - if (i > 0) { - recur(i - 1, a); - } -} - -// Signal handler that uses up more stack space than a goroutine will have. -static void ioHandler(int signo, siginfo_t* info, void* ctxt) { - char a[1024]; - - recur(4, a); - sigioSeen = 1; -} - -static jmp_buf jmp; -static char* nullPointer; - -// Signal handler for SIGSEGV on a C thread. -static void segvHandler(int signo, siginfo_t* info, void* ctxt) { - sigset_t mask; - int i; - - if (sigemptyset(&mask) < 0) { - die("sigemptyset"); - } - if (sigaddset(&mask, SIGSEGV) < 0) { - die("sigaddset"); - } - i = sigprocmask(SIG_UNBLOCK, &mask, NULL); - if (i != 0) { - fprintf(stderr, "sigprocmask: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - // Don't try this at home. - longjmp(jmp, signo); - - // We should never get here. - abort(); -} - -int main(int argc, char** argv) { - int verbose; - struct sigaction sa; - void* handle; - void (*fn)(void); - sigset_t mask; - int i; - struct timespec ts; - - verbose = argc > 2; - setvbuf(stdout, NULL, _IONBF, 0); - - // Call setsid so that we can use kill(0, SIGIO) below. - // Don't check the return value so that this works both from - // a job control shell and from a shell script. - setsid(); - - if (verbose) { - printf("calling sigaction\n"); - } - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = ioHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGIO, &sa, NULL) < 0) { - die("sigaction"); - } - - sa.sa_sigaction = segvHandler; - if (sigaction(SIGSEGV, &sa, NULL) < 0 || sigaction(SIGBUS, &sa, NULL) < 0) { - die("sigaction"); - } - - if (verbose) { - printf("calling dlopen\n"); - } - - handle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL); - if (handle == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling dlsym\n"); - } - - // Start some goroutines. - fn = (void(*)(void))dlsym(handle, "RunGoroutines"); - if (fn == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling RunGoroutines\n"); - } - - fn(); - - // Block SIGIO in this thread to make it more likely that it - // will be delivered to a goroutine. - - if (verbose) { - printf("calling pthread_sigmask\n"); - } - - if (sigemptyset(&mask) < 0) { - die("sigemptyset"); - } - if (sigaddset(&mask, SIGIO) < 0) { - die("sigaddset"); - } - i = pthread_sigmask(SIG_BLOCK, &mask, NULL); - if (i != 0) { - fprintf(stderr, "pthread_sigmask: %s\n", strerror(i)); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling kill\n"); - } - - if (kill(0, SIGIO) < 0) { - die("kill"); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - if (verbose) { - printf("calling setjmp\n"); - } - - // Test that a SIGSEGV on this thread is delivered to us. - if (setjmp(jmp) == 0) { - if (verbose) { - printf("triggering SIGSEGV\n"); - } - - *nullPointer = '\0'; - - fprintf(stderr, "continued after address error\n"); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling dlsym\n"); - } - - // Make sure that a SIGSEGV in Go causes a run-time panic. - fn = (void (*)(void))dlsym(handle, "TestSEGV"); - if (fn == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling TestSEGV\n"); - } - - fn(); - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/main5.c b/libgo/misc/cgo/testcshared/main5.c deleted file mode 100644 index 1bc9910..0000000 --- a/libgo/misc/cgo/testcshared/main5.c +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Test that a signal handler works in non-Go code when using -// os/signal.Notify. -// This is a lot like misc/cgo/testcarchive/main3.c. - -#include -#include -#include -#include -#include -#include -#include - -static void die(const char* msg) { - perror(msg); - exit(EXIT_FAILURE); -} - -static volatile sig_atomic_t sigioSeen; - -static void ioHandler(int signo, siginfo_t* info, void* ctxt) { - sigioSeen = 1; -} - -int main(int argc, char** argv) { - int verbose; - struct sigaction sa; - void* handle; - void (*fn1)(void); - int (*sawSIGIO)(void); - int i; - struct timespec ts; - - verbose = argc > 2; - setvbuf(stdout, NULL, _IONBF, 0); - - if (verbose) { - printf("calling sigaction\n"); - } - - memset(&sa, 0, sizeof sa); - sa.sa_sigaction = ioHandler; - if (sigemptyset(&sa.sa_mask) < 0) { - die("sigemptyset"); - } - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGIO, &sa, NULL) < 0) { - die("sigaction"); - } - - if (verbose) { - printf("calling dlopen\n"); - } - - handle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL); - if (handle == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - // At this point there should not be a Go signal handler - // installed for SIGIO. - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - sigioSeen = 0; - - // Tell the Go code to catch SIGIO. - - if (verbose) { - printf("calling dlsym\n"); - } - - fn1 = (void(*)(void))dlsym(handle, "CatchSIGIO"); - if (fn1 == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling CatchSIGIO\n"); - } - - fn1(); - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("calling dlsym\n"); - } - - // Check that the Go code saw SIGIO. - sawSIGIO = (int (*)(void))dlsym(handle, "SawSIGIO"); - if (sawSIGIO == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling SawSIGIO\n"); - } - - if (!sawSIGIO()) { - fprintf(stderr, "Go handler did not see SIGIO\n"); - exit(EXIT_FAILURE); - } - - if (sigioSeen != 0) { - fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n"); - exit(EXIT_FAILURE); - } - - // Tell the Go code to stop catching SIGIO. - - if (verbose) { - printf("calling dlsym\n"); - } - - fn1 = (void(*)(void))dlsym(handle, "ResetSIGIO"); - if (fn1 == NULL) { - fprintf(stderr, "%s\n", dlerror()); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("calling ResetSIGIO\n"); - } - - fn1(); - - if (verbose) { - printf("raising SIGIO\n"); - } - - if (raise(SIGIO) < 0) { - die("raise"); - } - - if (verbose) { - printf("calling SawSIGIO\n"); - } - - if (sawSIGIO()) { - fprintf(stderr, "Go handler saw SIGIO after Reset\n"); - exit(EXIT_FAILURE); - } - - if (verbose) { - printf("waiting for sigioSeen\n"); - } - - // Wait until the signal has been delivered. - i = 0; - while (!sigioSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for signal\n"); - exit(EXIT_FAILURE); - } - } - - printf("PASS\n"); - return 0; -} diff --git a/libgo/misc/cgo/testcshared/overlaydir_test.go b/libgo/misc/cgo/testcshared/overlaydir_test.go new file mode 100644 index 0000000..1eaabf6 --- /dev/null +++ b/libgo/misc/cgo/testcshared/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cshared_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go b/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go deleted file mode 100644 index 76a5323..0000000 --- a/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -//export GoFunc -func GoFunc() int { return 1 } - -func main() {} diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c b/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c deleted file mode 100644 index 0e8fac4..0000000 --- a/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "libtestgo2c2go.h" - -int CFunc(void) { - return (GoFunc() << 8) + 2; -} diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go b/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go deleted file mode 100644 index 17ba1eb..0000000 --- a/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// extern int CFunc(void); -import "C" - -import ( - "fmt" - "os" -) - -func main() { - got := C.CFunc() - const want = (1 << 8) | 2 - if got != want { - fmt.Printf("got %#x, want %#x\n", got, want) - os.Exit(1) - } -} diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go b/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go deleted file mode 100644 index 91bf308..0000000 --- a/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// #include "libtestgo2c2go.h" -import "C" - -import ( - "fmt" - "os" -) - -func main() { - got := C.GoFunc() - const want = 1 - if got != want { - fmt.Printf("got %#x, want %#x\n", got, want) - os.Exit(1) - } -} diff --git a/libgo/misc/cgo/testcshared/src/libgo/libgo.go b/libgo/misc/cgo/testcshared/src/libgo/libgo.go deleted file mode 100644 index 8a4bf79..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo/libgo.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - _ "p" - "syscall" - "time" -) - -import "C" - -var initCh = make(chan int, 1) -var ranMain bool - -func init() { - // emulate an exceedingly slow package initialization function - time.Sleep(100 * time.Millisecond) - initCh <- 42 -} - -func main() { - ranMain = true -} - -//export DidInitRun -func DidInitRun() bool { - select { - case x := <-initCh: - if x != 42 { - // Just in case initCh was not correctly made. - println("want init value of 42, got: ", x) - syscall.Exit(2) - } - return true - default: - return false - } -} - -//export DidMainRun -func DidMainRun() bool { - return ranMain -} diff --git a/libgo/misc/cgo/testcshared/src/libgo2/dup2.go b/libgo/misc/cgo/testcshared/src/libgo2/dup2.go deleted file mode 100644 index d343aa5..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo2/dup2.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux,!arm64,!riscv64 netbsd openbsd - -package main - -import "syscall" - -func dup2(oldfd, newfd int) error { - return syscall.Dup2(oldfd, newfd) -} diff --git a/libgo/misc/cgo/testcshared/src/libgo2/dup3.go b/libgo/misc/cgo/testcshared/src/libgo2/dup3.go deleted file mode 100644 index 459f0dc..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo2/dup3.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build linux,arm64 linux,riscv64 - -package main - -import "syscall" - -func dup2(oldfd, newfd int) error { - return syscall.Dup3(oldfd, newfd, 0) -} diff --git a/libgo/misc/cgo/testcshared/src/libgo2/libgo2.go b/libgo/misc/cgo/testcshared/src/libgo2/libgo2.go deleted file mode 100644 index e57c93b..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo2/libgo2.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd solaris - -package main - -// Test a shared library created by -buildmode=c-shared that does not -// export anything. - -import ( - "fmt" - "os" - "syscall" -) - -// To test this we want to communicate between the main program and -// the shared library without using any exported symbols. The init -// function creates a pipe and Dups the read end to a known number -// that the C code can also use. - -const ( - fd = 30 -) - -func init() { - var p [2]int - if e := syscall.Pipe(p[0:]); e != nil { - fmt.Fprintf(os.Stderr, "pipe: %v\n", e) - os.Exit(2) - } - - if e := dup2(p[0], fd); e != nil { - fmt.Fprintf(os.Stderr, "dup2: %v\n", e) - os.Exit(2) - } - - const str = "PASS" - if n, e := syscall.Write(p[1], []byte(str)); e != nil || n != len(str) { - fmt.Fprintf(os.Stderr, "write: %d %v\n", n, e) - os.Exit(2) - } - - if e := syscall.Close(p[1]); e != nil { - fmt.Fprintf(os.Stderr, "close: %v\n", e) - os.Exit(2) - } -} - -func main() { -} diff --git a/libgo/misc/cgo/testcshared/src/libgo4/libgo4.go b/libgo/misc/cgo/testcshared/src/libgo4/libgo4.go deleted file mode 100644 index ab40b75..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo4/libgo4.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -import ( - "fmt" - "os" - "runtime" -) - -// RunGoroutines starts some goroutines that don't do anything. -// The idea is to get some threads going, so that a signal will be delivered -// to a thread started by Go. -//export RunGoroutines -func RunGoroutines() { - for i := 0; i < 4; i++ { - go func() { - runtime.LockOSThread() - select {} - }() - } -} - -var P *byte - -// TestSEGV makes sure that an invalid address turns into a run-time Go panic. -//export TestSEGV -func TestSEGV() { - defer func() { - if recover() == nil { - fmt.Fprintln(os.Stderr, "no panic from segv") - os.Exit(1) - } - }() - *P = 0 - fmt.Fprintln(os.Stderr, "continued after segv") - os.Exit(1) -} - -func main() { -} diff --git a/libgo/misc/cgo/testcshared/src/libgo5/libgo5.go b/libgo/misc/cgo/testcshared/src/libgo5/libgo5.go deleted file mode 100644 index 94e5d21c..0000000 --- a/libgo/misc/cgo/testcshared/src/libgo5/libgo5.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -import ( - "os" - "os/signal" - "syscall" - "time" -) - -// The channel used to read SIGIO signals. -var sigioChan chan os.Signal - -// CatchSIGIO starts catching SIGIO signals. -//export CatchSIGIO -func CatchSIGIO() { - sigioChan = make(chan os.Signal, 1) - signal.Notify(sigioChan, syscall.SIGIO) -} - -// ResetSIGIO stops catching SIGIO signals. -//export ResetSIGIO -func ResetSIGIO() { - signal.Reset(syscall.SIGIO) -} - -// SawSIGIO returns whether we saw a SIGIO within a brief pause. -//export SawSIGIO -func SawSIGIO() C.int { - select { - case <-sigioChan: - return 1 - case <-time.After(100 * time.Millisecond): - return 0 - } -} - -func main() { -} diff --git a/libgo/misc/cgo/testcshared/src/p/p.go b/libgo/misc/cgo/testcshared/src/p/p.go deleted file mode 100644 index 0f02cf3..0000000 --- a/libgo/misc/cgo/testcshared/src/p/p.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package p - -import "C" - -//export FromPkg -func FromPkg() int32 { return 1024 } - -//export Divu -func Divu(a, b uint32) uint32 { return a / b } diff --git a/libgo/misc/cgo/testcshared/testdata/go2c2go/go/shlib.go b/libgo/misc/cgo/testcshared/testdata/go2c2go/go/shlib.go new file mode 100644 index 0000000..76a5323 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/go2c2go/go/shlib.go @@ -0,0 +1,12 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +//export GoFunc +func GoFunc() int { return 1 } + +func main() {} diff --git a/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/c.c b/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/c.c new file mode 100644 index 0000000..0e8fac4 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/c.c @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "libtestgo2c2go.h" + +int CFunc(void) { + return (GoFunc() << 8) + 2; +} diff --git a/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/main.go b/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/main.go new file mode 100644 index 0000000..17ba1eb --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/go2c2go/m1/main.go @@ -0,0 +1,22 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// extern int CFunc(void); +import "C" + +import ( + "fmt" + "os" +) + +func main() { + got := C.CFunc() + const want = (1 << 8) | 2 + if got != want { + fmt.Printf("got %#x, want %#x\n", got, want) + os.Exit(1) + } +} diff --git a/libgo/misc/cgo/testcshared/testdata/go2c2go/m2/main.go b/libgo/misc/cgo/testcshared/testdata/go2c2go/m2/main.go new file mode 100644 index 0000000..91bf308 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/go2c2go/m2/main.go @@ -0,0 +1,22 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// #include "libtestgo2c2go.h" +import "C" + +import ( + "fmt" + "os" +) + +func main() { + got := C.GoFunc() + const want = 1 + if got != want { + fmt.Printf("got %#x, want %#x\n", got, want) + os.Exit(1) + } +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo/libgo.go b/libgo/misc/cgo/testcshared/testdata/libgo/libgo.go new file mode 100644 index 0000000..0634417 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo/libgo.go @@ -0,0 +1,46 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "syscall" + _ "testcshared/p" + "time" +) + +import "C" + +var initCh = make(chan int, 1) +var ranMain bool + +func init() { + // emulate an exceedingly slow package initialization function + time.Sleep(100 * time.Millisecond) + initCh <- 42 +} + +func main() { + ranMain = true +} + +//export DidInitRun +func DidInitRun() bool { + select { + case x := <-initCh: + if x != 42 { + // Just in case initCh was not correctly made. + println("want init value of 42, got: ", x) + syscall.Exit(2) + } + return true + default: + return false + } +} + +//export DidMainRun +func DidMainRun() bool { + return ranMain +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go new file mode 100644 index 0000000..d18f0b1 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup2.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux,!arm64 netbsd openbsd + +package main + +import "syscall" + +func dup2(oldfd, newfd int) error { + return syscall.Dup2(oldfd, newfd) +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go new file mode 100644 index 0000000..c9c65a6 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo2/dup3.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build linux,arm64 + +package main + +import "syscall" + +func dup2(oldfd, newfd int) error { + return syscall.Dup3(oldfd, newfd, 0) +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo2/libgo2.go b/libgo/misc/cgo/testcshared/testdata/libgo2/libgo2.go new file mode 100644 index 0000000..e57c93b --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo2/libgo2.go @@ -0,0 +1,52 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package main + +// Test a shared library created by -buildmode=c-shared that does not +// export anything. + +import ( + "fmt" + "os" + "syscall" +) + +// To test this we want to communicate between the main program and +// the shared library without using any exported symbols. The init +// function creates a pipe and Dups the read end to a known number +// that the C code can also use. + +const ( + fd = 30 +) + +func init() { + var p [2]int + if e := syscall.Pipe(p[0:]); e != nil { + fmt.Fprintf(os.Stderr, "pipe: %v\n", e) + os.Exit(2) + } + + if e := dup2(p[0], fd); e != nil { + fmt.Fprintf(os.Stderr, "dup2: %v\n", e) + os.Exit(2) + } + + const str = "PASS" + if n, e := syscall.Write(p[1], []byte(str)); e != nil || n != len(str) { + fmt.Fprintf(os.Stderr, "write: %d %v\n", n, e) + os.Exit(2) + } + + if e := syscall.Close(p[1]); e != nil { + fmt.Fprintf(os.Stderr, "close: %v\n", e) + os.Exit(2) + } +} + +func main() { +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo4/libgo4.go b/libgo/misc/cgo/testcshared/testdata/libgo4/libgo4.go new file mode 100644 index 0000000..ab40b75 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo4/libgo4.go @@ -0,0 +1,45 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +import ( + "fmt" + "os" + "runtime" +) + +// RunGoroutines starts some goroutines that don't do anything. +// The idea is to get some threads going, so that a signal will be delivered +// to a thread started by Go. +//export RunGoroutines +func RunGoroutines() { + for i := 0; i < 4; i++ { + go func() { + runtime.LockOSThread() + select {} + }() + } +} + +var P *byte + +// TestSEGV makes sure that an invalid address turns into a run-time Go panic. +//export TestSEGV +func TestSEGV() { + defer func() { + if recover() == nil { + fmt.Fprintln(os.Stderr, "no panic from segv") + os.Exit(1) + } + }() + *P = 0 + fmt.Fprintln(os.Stderr, "continued after segv") + os.Exit(1) +} + +func main() { +} diff --git a/libgo/misc/cgo/testcshared/testdata/libgo5/libgo5.go b/libgo/misc/cgo/testcshared/testdata/libgo5/libgo5.go new file mode 100644 index 0000000..94e5d21c --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/libgo5/libgo5.go @@ -0,0 +1,44 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +import ( + "os" + "os/signal" + "syscall" + "time" +) + +// The channel used to read SIGIO signals. +var sigioChan chan os.Signal + +// CatchSIGIO starts catching SIGIO signals. +//export CatchSIGIO +func CatchSIGIO() { + sigioChan = make(chan os.Signal, 1) + signal.Notify(sigioChan, syscall.SIGIO) +} + +// ResetSIGIO stops catching SIGIO signals. +//export ResetSIGIO +func ResetSIGIO() { + signal.Reset(syscall.SIGIO) +} + +// SawSIGIO returns whether we saw a SIGIO within a brief pause. +//export SawSIGIO +func SawSIGIO() C.int { + select { + case <-sigioChan: + return 1 + case <-time.After(100 * time.Millisecond): + return 0 + } +} + +func main() { +} diff --git a/libgo/misc/cgo/testcshared/testdata/main0.c b/libgo/misc/cgo/testcshared/testdata/main0.c new file mode 100644 index 0000000..39ef7e3 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main0.c @@ -0,0 +1,42 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include + +#include "p.h" +#include "libgo.h" + +// Tests libgo.so to export the following functions. +// int8_t DidInitRun(); +// int8_t DidMainRun(); +// int32_t FromPkg(); +// uint32_t Divu(uint32_t, uint32_t); +int main(void) { + int8_t ran_init = DidInitRun(); + if (!ran_init) { + fprintf(stderr, "ERROR: DidInitRun returned unexpected results: %d\n", + ran_init); + return 1; + } + int8_t ran_main = DidMainRun(); + if (ran_main) { + fprintf(stderr, "ERROR: DidMainRun returned unexpected results: %d\n", + ran_main); + return 1; + } + int32_t from_pkg = FromPkg(); + if (from_pkg != 1024) { + fprintf(stderr, "ERROR: FromPkg=%d, want %d\n", from_pkg, 1024); + return 1; + } + uint32_t divu = Divu(2264, 31); + if (divu != 73) { + fprintf(stderr, "ERROR: Divu(2264, 31)=%d, want %d\n", divu, 73); + return 1; + } + // test.bash looks for "PASS" to ensure this program has reached the end. + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/main1.c b/libgo/misc/cgo/testcshared/testdata/main1.c new file mode 100644 index 0000000..420dd1e --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main1.c @@ -0,0 +1,69 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include + +int check_int8(void* handle, const char* fname, int8_t want) { + int8_t (*fn)(); + fn = (int8_t (*)())dlsym(handle, fname); + if (!fn) { + fprintf(stderr, "ERROR: missing %s: %s\n", fname, dlerror()); + return 1; + } + signed char ret = fn(); + if (ret != want) { + fprintf(stderr, "ERROR: %s=%d, want %d\n", fname, ret, want); + return 1; + } + return 0; +} + +int check_int32(void* handle, const char* fname, int32_t want) { + int32_t (*fn)(); + fn = (int32_t (*)())dlsym(handle, fname); + if (!fn) { + fprintf(stderr, "ERROR: missing %s: %s\n", fname, dlerror()); + return 1; + } + int32_t ret = fn(); + if (ret != want) { + fprintf(stderr, "ERROR: %s=%d, want %d\n", fname, ret, want); + return 1; + } + return 0; +} + +// Tests libgo.so to export the following functions. +// int8_t DidInitRun() // returns true +// int8_t DidMainRun() // returns true +// int32_t FromPkg() // returns 1024 +int main(int argc, char** argv) { + void* handle = dlopen(argv[1], RTLD_LAZY | RTLD_GLOBAL); + if (!handle) { + fprintf(stderr, "ERROR: failed to open the shared library: %s\n", + dlerror()); + return 2; + } + + int ret = 0; + ret = check_int8(handle, "DidInitRun", 1); + if (ret != 0) { + return ret; + } + + ret = check_int8(handle, "DidMainRun", 0); + if (ret != 0) { + return ret; + } + + ret = check_int32(handle, "FromPkg", 1024); + if (ret != 0) { + return ret; + } + // test.bash looks for "PASS" to ensure this program has reached the end. + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/main2.c b/libgo/misc/cgo/testcshared/testdata/main2.c new file mode 100644 index 0000000..f89bcca --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main2.c @@ -0,0 +1,56 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include +#include +#include +#include + +#define fd (30) + +// Tests libgo2.so, which does not export any functions. +// Read a string from the file descriptor and print it. +int main(void) { + int i; + ssize_t n; + char buf[20]; + struct timespec ts; + + // The descriptor will be initialized in a thread, so we have to + // give a chance to get opened. + for (i = 0; i < 200; i++) { + n = read(fd, buf, sizeof buf); + if (n >= 0) + break; + if (errno != EBADF && errno != EINVAL) { + fprintf(stderr, "BUG: read: %s\n", strerror(errno)); + return 2; + } + + // An EBADF error means that the shared library has not opened the + // descriptor yet. + ts.tv_sec = 0; + ts.tv_nsec = 10000000; + nanosleep(&ts, NULL); + } + + if (n < 0) { + fprintf(stderr, "BUG: failed to read any data from pipe\n"); + return 2; + } + + if (n == 0) { + fprintf(stderr, "BUG: unexpected EOF\n"); + return 2; + } + + if (n == sizeof buf) { + n--; + } + buf[n] = '\0'; + printf("%s\n", buf); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/main3.c b/libgo/misc/cgo/testcshared/testdata/main3.c new file mode 100644 index 0000000..49cc055 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main3.c @@ -0,0 +1,29 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include +#include + +// Tests "main.main" is exported on android/arm, +// which golang.org/x/mobile/app depends on. +int main(int argc, char** argv) { + void* handle = dlopen(argv[1], RTLD_LAZY | RTLD_GLOBAL); + if (!handle) { + fprintf(stderr, "ERROR: failed to open the shared library: %s\n", + dlerror()); + return 2; + } + + uintptr_t main_fn = (uintptr_t)dlsym(handle, "main.main"); + if (!main_fn) { + fprintf(stderr, "ERROR: missing main.main: %s\n", dlerror()); + return 2; + } + + // TODO(hyangah): check that main.main can run. + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/main4.c b/libgo/misc/cgo/testcshared/testdata/main4.c new file mode 100644 index 0000000..355cdef --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main4.c @@ -0,0 +1,215 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that a signal handler that uses up stack space does not crash +// if the signal is delivered to a thread running a goroutine. +// This is a lot like misc/cgo/testcarchive/main2.c. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void die(const char* msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +static volatile sig_atomic_t sigioSeen; + +// Use up some stack space. +static void recur(int i, char *p) { + char a[1024]; + + *p = '\0'; + if (i > 0) { + recur(i - 1, a); + } +} + +// Signal handler that uses up more stack space than a goroutine will have. +static void ioHandler(int signo, siginfo_t* info, void* ctxt) { + char a[1024]; + + recur(4, a); + sigioSeen = 1; +} + +static jmp_buf jmp; +static char* nullPointer; + +// Signal handler for SIGSEGV on a C thread. +static void segvHandler(int signo, siginfo_t* info, void* ctxt) { + sigset_t mask; + int i; + + if (sigemptyset(&mask) < 0) { + die("sigemptyset"); + } + if (sigaddset(&mask, SIGSEGV) < 0) { + die("sigaddset"); + } + i = sigprocmask(SIG_UNBLOCK, &mask, NULL); + if (i != 0) { + fprintf(stderr, "sigprocmask: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + // Don't try this at home. + longjmp(jmp, signo); + + // We should never get here. + abort(); +} + +int main(int argc, char** argv) { + int verbose; + struct sigaction sa; + void* handle; + void (*fn)(void); + sigset_t mask; + int i; + struct timespec ts; + + verbose = argc > 2; + setvbuf(stdout, NULL, _IONBF, 0); + + // Call setsid so that we can use kill(0, SIGIO) below. + // Don't check the return value so that this works both from + // a job control shell and from a shell script. + setsid(); + + if (verbose) { + printf("calling sigaction\n"); + } + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = ioHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGIO, &sa, NULL) < 0) { + die("sigaction"); + } + + sa.sa_sigaction = segvHandler; + if (sigaction(SIGSEGV, &sa, NULL) < 0 || sigaction(SIGBUS, &sa, NULL) < 0) { + die("sigaction"); + } + + if (verbose) { + printf("calling dlopen\n"); + } + + handle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL); + if (handle == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling dlsym\n"); + } + + // Start some goroutines. + fn = (void(*)(void))dlsym(handle, "RunGoroutines"); + if (fn == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling RunGoroutines\n"); + } + + fn(); + + // Block SIGIO in this thread to make it more likely that it + // will be delivered to a goroutine. + + if (verbose) { + printf("calling pthread_sigmask\n"); + } + + if (sigemptyset(&mask) < 0) { + die("sigemptyset"); + } + if (sigaddset(&mask, SIGIO) < 0) { + die("sigaddset"); + } + i = pthread_sigmask(SIG_BLOCK, &mask, NULL); + if (i != 0) { + fprintf(stderr, "pthread_sigmask: %s\n", strerror(i)); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling kill\n"); + } + + if (kill(0, SIGIO) < 0) { + die("kill"); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + if (verbose) { + printf("calling setjmp\n"); + } + + // Test that a SIGSEGV on this thread is delivered to us. + if (setjmp(jmp) == 0) { + if (verbose) { + printf("triggering SIGSEGV\n"); + } + + *nullPointer = '\0'; + + fprintf(stderr, "continued after address error\n"); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling dlsym\n"); + } + + // Make sure that a SIGSEGV in Go causes a run-time panic. + fn = (void (*)(void))dlsym(handle, "TestSEGV"); + if (fn == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling TestSEGV\n"); + } + + fn(); + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/main5.c b/libgo/misc/cgo/testcshared/testdata/main5.c new file mode 100644 index 0000000..1bc9910 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/main5.c @@ -0,0 +1,199 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that a signal handler works in non-Go code when using +// os/signal.Notify. +// This is a lot like misc/cgo/testcarchive/main3.c. + +#include +#include +#include +#include +#include +#include +#include + +static void die(const char* msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +static volatile sig_atomic_t sigioSeen; + +static void ioHandler(int signo, siginfo_t* info, void* ctxt) { + sigioSeen = 1; +} + +int main(int argc, char** argv) { + int verbose; + struct sigaction sa; + void* handle; + void (*fn1)(void); + int (*sawSIGIO)(void); + int i; + struct timespec ts; + + verbose = argc > 2; + setvbuf(stdout, NULL, _IONBF, 0); + + if (verbose) { + printf("calling sigaction\n"); + } + + memset(&sa, 0, sizeof sa); + sa.sa_sigaction = ioHandler; + if (sigemptyset(&sa.sa_mask) < 0) { + die("sigemptyset"); + } + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGIO, &sa, NULL) < 0) { + die("sigaction"); + } + + if (verbose) { + printf("calling dlopen\n"); + } + + handle = dlopen(argv[1], RTLD_NOW | RTLD_GLOBAL); + if (handle == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + // At this point there should not be a Go signal handler + // installed for SIGIO. + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + sigioSeen = 0; + + // Tell the Go code to catch SIGIO. + + if (verbose) { + printf("calling dlsym\n"); + } + + fn1 = (void(*)(void))dlsym(handle, "CatchSIGIO"); + if (fn1 == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling CatchSIGIO\n"); + } + + fn1(); + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("calling dlsym\n"); + } + + // Check that the Go code saw SIGIO. + sawSIGIO = (int (*)(void))dlsym(handle, "SawSIGIO"); + if (sawSIGIO == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling SawSIGIO\n"); + } + + if (!sawSIGIO()) { + fprintf(stderr, "Go handler did not see SIGIO\n"); + exit(EXIT_FAILURE); + } + + if (sigioSeen != 0) { + fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n"); + exit(EXIT_FAILURE); + } + + // Tell the Go code to stop catching SIGIO. + + if (verbose) { + printf("calling dlsym\n"); + } + + fn1 = (void(*)(void))dlsym(handle, "ResetSIGIO"); + if (fn1 == NULL) { + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("calling ResetSIGIO\n"); + } + + fn1(); + + if (verbose) { + printf("raising SIGIO\n"); + } + + if (raise(SIGIO) < 0) { + die("raise"); + } + + if (verbose) { + printf("calling SawSIGIO\n"); + } + + if (sawSIGIO()) { + fprintf(stderr, "Go handler saw SIGIO after Reset\n"); + exit(EXIT_FAILURE); + } + + if (verbose) { + printf("waiting for sigioSeen\n"); + } + + // Wait until the signal has been delivered. + i = 0; + while (!sigioSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for signal\n"); + exit(EXIT_FAILURE); + } + } + + printf("PASS\n"); + return 0; +} diff --git a/libgo/misc/cgo/testcshared/testdata/p/p.go b/libgo/misc/cgo/testcshared/testdata/p/p.go new file mode 100644 index 0000000..0f02cf3 --- /dev/null +++ b/libgo/misc/cgo/testcshared/testdata/p/p.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "C" + +//export FromPkg +func FromPkg() int32 { return 1024 } + +//export Divu +func Divu(a, b uint32) uint32 { return a / b } diff --git a/libgo/misc/cgo/testgodefs/anonunion.go b/libgo/misc/cgo/testgodefs/anonunion.go deleted file mode 100644 index 18840f2..0000000 --- a/libgo/misc/cgo/testgodefs/anonunion.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// +build ignore - -package main - -// This file tests that when cgo -godefs sees a struct with a field -// that is an anonymous union, the first field in the union is -// promoted to become a field of the struct. See issue 6677 for -// background. - -/* -typedef struct { - union { - long l; - int c; - }; -} t; -*/ -import "C" - -// Input for cgo -godefs. - -type T C.t diff --git a/libgo/misc/cgo/testgodefs/fieldtypedef.go b/libgo/misc/cgo/testgodefs/fieldtypedef.go deleted file mode 100644 index 45c0bf8..0000000 --- a/libgo/misc/cgo/testgodefs/fieldtypedef.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserve d. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// +build ignore - -package main - -/* -struct S1 { int f1; }; -struct S2 { struct S1 s1; }; -typedef struct S1 S1Type; -typedef struct S2 S2Type; -*/ -import "C" - -type S1 C.S1Type -type S2 C.S2Type diff --git a/libgo/misc/cgo/testgodefs/issue8478.go b/libgo/misc/cgo/testgodefs/issue8478.go deleted file mode 100644 index 2321446..0000000 --- a/libgo/misc/cgo/testgodefs/issue8478.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -// -// +build ignore - -package main - -// Issue 8478. Test that void* is consistently mapped to *byte. - -/* -typedef struct { - void *p; - void **q; - void ***r; -} s; -*/ -import "C" - -type Issue8478 C.s diff --git a/libgo/misc/cgo/testgodefs/main.go b/libgo/misc/cgo/testgodefs/main.go deleted file mode 100644 index 1ce0fd0..0000000 --- a/libgo/misc/cgo/testgodefs/main.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Test that the struct field in anonunion.go was promoted. -var v1 T -var v2 = v1.L - -// Test that P, Q, and R all point to byte. -var v3 = Issue8478{P: (*byte)(nil), Q: (**byte)(nil), R: (***byte)(nil)} - -func main() { -} diff --git a/libgo/misc/cgo/testgodefs/test.bash b/libgo/misc/cgo/testgodefs/test.bash index 012d007..e4ce2ee 100644 --- a/libgo/misc/cgo/testgodefs/test.bash +++ b/libgo/misc/cgo/testgodefs/test.bash @@ -9,6 +9,8 @@ # import "C" block. Add more tests here. FILE_PREFIXES="anonunion issue8478 fieldtypedef" +cd testdata + RM= for FP in $FILE_PREFIXES do @@ -16,7 +18,7 @@ do RM="${RM} ${FP}_defs.go" done -go build . && ./testgodefs +go build -o testgodefs . && ./testgodefs EXIT=$? rm -rf _obj testgodefs ${RM} exit $EXIT diff --git a/libgo/misc/cgo/testgodefs/testdata/anonunion.go b/libgo/misc/cgo/testgodefs/testdata/anonunion.go new file mode 100644 index 0000000..18840f2 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/anonunion.go @@ -0,0 +1,26 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// +build ignore + +package main + +// This file tests that when cgo -godefs sees a struct with a field +// that is an anonymous union, the first field in the union is +// promoted to become a field of the struct. See issue 6677 for +// background. + +/* +typedef struct { + union { + long l; + int c; + }; +} t; +*/ +import "C" + +// Input for cgo -godefs. + +type T C.t diff --git a/libgo/misc/cgo/testgodefs/testdata/fieldtypedef.go b/libgo/misc/cgo/testgodefs/testdata/fieldtypedef.go new file mode 100644 index 0000000..45c0bf8 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/fieldtypedef.go @@ -0,0 +1,18 @@ +// Copyright 2018 The Go Authors. All rights reserve d. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// +build ignore + +package main + +/* +struct S1 { int f1; }; +struct S2 { struct S1 s1; }; +typedef struct S1 S1Type; +typedef struct S2 S2Type; +*/ +import "C" + +type S1 C.S1Type +type S2 C.S2Type diff --git a/libgo/misc/cgo/testgodefs/testdata/issue8478.go b/libgo/misc/cgo/testgodefs/testdata/issue8478.go new file mode 100644 index 0000000..2321446 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/issue8478.go @@ -0,0 +1,20 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// +build ignore + +package main + +// Issue 8478. Test that void* is consistently mapped to *byte. + +/* +typedef struct { + void *p; + void **q; + void ***r; +} s; +*/ +import "C" + +type Issue8478 C.s diff --git a/libgo/misc/cgo/testgodefs/testdata/main.go b/libgo/misc/cgo/testgodefs/testdata/main.go new file mode 100644 index 0000000..1ce0fd0 --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testdata/main.go @@ -0,0 +1,15 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Test that the struct field in anonunion.go was promoted. +var v1 T +var v2 = v1.L + +// Test that P, Q, and R all point to byte. +var v3 = Issue8478{P: (*byte)(nil), Q: (**byte)(nil), R: (***byte)(nil)} + +func main() { +} diff --git a/libgo/misc/cgo/testplugin/altpath/src/common/common.go b/libgo/misc/cgo/testplugin/altpath/src/common/common.go deleted file mode 100644 index 505ba02..0000000 --- a/libgo/misc/cgo/testplugin/altpath/src/common/common.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package common - -var X int - -func init() { - X = 4 -} diff --git a/libgo/misc/cgo/testplugin/altpath/src/plugin-mismatch/main.go b/libgo/misc/cgo/testplugin/altpath/src/plugin-mismatch/main.go deleted file mode 100644 index 8aacafc..0000000 --- a/libgo/misc/cgo/testplugin/altpath/src/plugin-mismatch/main.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// // No C code required. -import "C" - -// The common package imported here does not match the common package -// imported by plugin1. A program that attempts to load plugin1 and -// plugin-mismatch should produce an error. -import "common" - -func ReadCommonX() int { - return common.X -} diff --git a/libgo/misc/cgo/testplugin/altpath/testdata/common/common.go b/libgo/misc/cgo/testplugin/altpath/testdata/common/common.go new file mode 100644 index 0000000..505ba02 --- /dev/null +++ b/libgo/misc/cgo/testplugin/altpath/testdata/common/common.go @@ -0,0 +1,11 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package common + +var X int + +func init() { + X = 4 +} diff --git a/libgo/misc/cgo/testplugin/altpath/testdata/plugin-mismatch/main.go b/libgo/misc/cgo/testplugin/altpath/testdata/plugin-mismatch/main.go new file mode 100644 index 0000000..bfb4ba4 --- /dev/null +++ b/libgo/misc/cgo/testplugin/altpath/testdata/plugin-mismatch/main.go @@ -0,0 +1,17 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// // No C code required. +import "C" + +// The common package imported here does not match the common package +// imported by plugin1. A program that attempts to load plugin1 and +// plugin-mismatch should produce an error. +import "testplugin/common" + +func ReadCommonX() int { + return common.X +} diff --git a/libgo/misc/cgo/testplugin/overlaydir_test.go b/libgo/misc/cgo/testplugin/overlaydir_test.go new file mode 100644 index 0000000..b68436a --- /dev/null +++ b/libgo/misc/cgo/testplugin/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package plugin_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testplugin/plugin_test.go b/libgo/misc/cgo/testplugin/plugin_test.go new file mode 100644 index 0000000..7e2b6eb --- /dev/null +++ b/libgo/misc/cgo/testplugin/plugin_test.go @@ -0,0 +1,203 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package plugin_test + +import ( + "bytes" + "context" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +var gcflags string = os.Getenv("GO_GCFLAGS") + +func TestMain(m *testing.M) { + flag.Parse() + if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { + fmt.Printf("SKIP - short mode and $GO_BUILDER_NAME not set\n") + os.Exit(0) + } + log.SetFlags(log.Lshortfile) + os.Exit(testMain(m)) +} + +func testMain(m *testing.M) int { + // Copy testdata into GOPATH/src/testarchive, along with a go.mod file + // declaring the same path. + + GOPATH, err := ioutil.TempDir("", "plugin_test") + if err != nil { + log.Panic(err) + } + defer os.RemoveAll(GOPATH) + + modRoot := filepath.Join(GOPATH, "src", "testplugin") + altRoot := filepath.Join(GOPATH, "alt", "src", "testplugin") + for srcRoot, dstRoot := range map[string]string{ + "testdata": modRoot, + filepath.Join("altpath", "testdata"): altRoot, + } { + if err := overlayDir(dstRoot, srcRoot); err != nil { + log.Panic(err) + } + if err := ioutil.WriteFile(filepath.Join(dstRoot, "go.mod"), []byte("module testplugin\n"), 0666); err != nil { + log.Panic(err) + } + } + + os.Setenv("GOPATH", filepath.Join(GOPATH, "alt")) + if err := os.Chdir(altRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", altRoot) + goCmd(nil, "build", "-buildmode=plugin", "-o", filepath.Join(modRoot, "plugin-mismatch.so"), "./plugin-mismatch") + + os.Setenv("GOPATH", GOPATH) + if err := os.Chdir(modRoot); err != nil { + log.Panic(err) + } + os.Setenv("PWD", modRoot) + + os.Setenv("LD_LIBRARY_PATH", modRoot) + + goCmd(nil, "build", "-i", "-buildmode=plugin", "./plugin1") + goCmd(nil, "build", "-buildmode=plugin", "./plugin2") + so, err := ioutil.ReadFile("plugin2.so") + if err != nil { + log.Panic(err) + } + if err := ioutil.WriteFile("plugin2-dup.so", so, 0444); err != nil { + log.Panic(err) + } + + goCmd(nil, "build", "-buildmode=plugin", "-o=sub/plugin1.so", "./sub/plugin1") + goCmd(nil, "build", "-buildmode=plugin", "-o=unnamed1.so", "./unnamed1/main.go") + goCmd(nil, "build", "-buildmode=plugin", "-o=unnamed2.so", "./unnamed2/main.go") + goCmd(nil, "build", "-o", "host.exe", "./host") + + return m.Run() +} + +func goCmd(t *testing.T, op string, args ...string) { + if t != nil { + t.Helper() + } + run(t, "go", append([]string{op, "-gcflags", gcflags}, args...)...) +} + +func run(t *testing.T, bin string, args ...string) string { + cmd := exec.Command(bin, args...) + cmd.Stderr = new(strings.Builder) + out, err := cmd.Output() + if err != nil { + if t == nil { + log.Panicf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + } else { + t.Helper() + t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + } + } + + return string(bytes.TrimSpace(out)) +} + +func TestDWARFSections(t *testing.T) { + // test that DWARF sections are emitted for plugins and programs importing "plugin" + if runtime.GOOS != "darwin" { + // On macOS, for some reason, the linker doesn't add debug sections to .so, + // see issue #27502. + goCmd(t, "run", "./checkdwarf/main.go", "plugin2.so", "plugin2.UnexportedNameReuse") + } + goCmd(t, "run", "./checkdwarf/main.go", "./host.exe", "main.main") +} + +func TestRunHost(t *testing.T) { + run(t, "./host.exe") +} + +func TestUniqueTypesAndItabs(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "./iface_a") + goCmd(t, "build", "-buildmode=plugin", "./iface_b") + goCmd(t, "build", "-o", "iface.exe", "./iface") + run(t, "./iface.exe") +} + +func TestIssue18676(t *testing.T) { + // make sure we don't add the same itab twice. + // The buggy code hangs forever, so use a timeout to check for that. + goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./issue18676/plugin.go") + goCmd(t, "build", "-o", "issue18676.exe", "./issue18676/main.go") + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + cmd := exec.CommandContext(ctx, "./issue18676.exe") + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out) + } +} + +func TestIssue19534(t *testing.T) { + // Test that we can load a plugin built in a path with non-alpha characters. + goCmd(t, "build", "-buildmode=plugin", "-ldflags='-pluginpath=issue.19534'", "-o", "plugin.so", "./issue19534/plugin.go") + goCmd(t, "build", "-o", "issue19534.exe", "./issue19534/main.go") + run(t, "./issue19534.exe") +} + +func TestIssue18584(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./issue18584/plugin.go") + goCmd(t, "build", "-o", "issue18584.exe", "./issue18584/main.go") + run(t, "./issue18584.exe") +} + +func TestIssue19418(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-ldflags=-X main.Val=linkstr", "-o", "plugin.so", "./issue19418/plugin.go") + goCmd(t, "build", "-o", "issue19418.exe", "./issue19418/main.go") + run(t, "./issue19418.exe") +} + +func TestIssue19529(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./issue19529/plugin.go") +} + +func TestIssue22175(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "issue22175_plugin1.so", "./issue22175/plugin1.go") + goCmd(t, "build", "-buildmode=plugin", "-o", "issue22175_plugin2.so", "./issue22175/plugin2.go") + goCmd(t, "build", "-o", "issue22175.exe", "./issue22175/main.go") + run(t, "./issue22175.exe") +} + +func TestIssue22295(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "issue.22295.so", "./issue22295.pkg") + goCmd(t, "build", "-o", "issue22295.exe", "./issue22295.pkg/main.go") + run(t, "./issue22295.exe") +} + +func TestIssue24351(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "issue24351.so", "./issue24351/plugin.go") + goCmd(t, "build", "-o", "issue24351.exe", "./issue24351/main.go") + run(t, "./issue24351.exe") +} + +func TestIssue25756(t *testing.T) { + goCmd(t, "build", "-buildmode=plugin", "-o", "life.so", "./issue25756/plugin") + goCmd(t, "build", "-o", "issue25756.exe", "./issue25756/main.go") + // Fails intermittently, but 20 runs should cause the failure + for n := 20; n > 0; n-- { + t.Run(fmt.Sprint(n), func(t *testing.T) { + t.Parallel() + run(t, "./issue25756.exe") + }) + } +} diff --git a/libgo/misc/cgo/testplugin/src/checkdwarf/main.go b/libgo/misc/cgo/testplugin/src/checkdwarf/main.go deleted file mode 100644 index 7886c83..0000000 --- a/libgo/misc/cgo/testplugin/src/checkdwarf/main.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Usage: -// -// checkdwarf -// -// Opens , which must be an executable or a library and checks that -// there is an entry in .debug_info whose name ends in - -package main - -import ( - "debug/dwarf" - "debug/elf" - "debug/macho" - "debug/pe" - "fmt" - "os" - "strings" -) - -func usage() { - fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n") -} - -type dwarfer interface { - DWARF() (*dwarf.Data, error) -} - -func openElf(path string) dwarfer { - exe, err := elf.Open(path) - if err != nil { - return nil - } - return exe -} - -func openMacho(path string) dwarfer { - exe, err := macho.Open(path) - if err != nil { - return nil - } - return exe -} - -func openPE(path string) dwarfer { - exe, err := pe.Open(path) - if err != nil { - return nil - } - return exe -} - -func main() { - if len(os.Args) != 3 { - usage() - } - - exePath := os.Args[1] - dieSuffix := os.Args[2] - - var exe dwarfer - - for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} { - exe = openfn(exePath) - if exe != nil { - break - } - } - - if exe == nil { - fmt.Fprintf(os.Stderr, "could not open %s\n", exePath) - os.Exit(1) - } - - data, err := exe.DWARF() - if err != nil { - fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err) - os.Exit(1) - } - - rdr := data.Reader() - for { - e, err := rdr.Next() - if err != nil { - fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err) - os.Exit(1) - } - if e == nil { - break - } - name, hasname := e.Val(dwarf.AttrName).(string) - if !hasname { - continue - } - if strings.HasSuffix(name, dieSuffix) { - // found - os.Exit(0) - } - } - - fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix) - os.Exit(1) -} diff --git a/libgo/misc/cgo/testplugin/src/common/common.go b/libgo/misc/cgo/testplugin/src/common/common.go deleted file mode 100644 index b064e6b..0000000 --- a/libgo/misc/cgo/testplugin/src/common/common.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package common - -var X int - -func init() { - X = 3 -} diff --git a/libgo/misc/cgo/testplugin/src/host/host.go b/libgo/misc/cgo/testplugin/src/host/host.go deleted file mode 100644 index 0ca17da..0000000 --- a/libgo/misc/cgo/testplugin/src/host/host.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "log" - "path/filepath" - "plugin" - "strings" - - "common" -) - -func init() { - common.X *= 5 -} - -// testUnnamed tests that two plugins built with .go files passed on -// the command line do not have overlapping symbols. That is, -// unnamed1.so/FuncInt and unnamed2.so/FuncInt should be distinct functions. -func testUnnamed() { - p, err := plugin.Open("unnamed1.so") - if err != nil { - log.Fatalf(`plugin.Open("unnamed1.so"): %v`, err) - } - fn, err := p.Lookup("FuncInt") - if err != nil { - log.Fatalf(`unnamed1.so: Lookup("FuncInt") failed: %v`, err) - } - if got, want := fn.(func() int)(), 1; got != want { - log.Fatalf("unnamed1.so: FuncInt()=%d, want %d", got, want) - } - - p, err = plugin.Open("unnamed2.so") - if err != nil { - log.Fatalf(`plugin.Open("unnamed2.so"): %v`, err) - } - fn, err = p.Lookup("FuncInt") - if err != nil { - log.Fatalf(`unnamed2.so: Lookup("FuncInt") failed: %v`, err) - } - if got, want := fn.(func() int)(), 2; got != want { - log.Fatalf("unnamed2.so: FuncInt()=%d, want %d", got, want) - } -} - -func main() { - if got, want := common.X, 3*5; got != want { - log.Fatalf("before plugin load common.X=%d, want %d", got, want) - } - - p, err := plugin.Open("plugin1.so") - if err != nil { - log.Fatalf("plugin.Open failed: %v", err) - } - - const wantX = 3 * 5 * 7 - if got := common.X; got != wantX { - log.Fatalf("after plugin load common.X=%d, want %d", got, wantX) - } - - seven, err := p.Lookup("Seven") - if err != nil { - log.Fatalf(`Lookup("Seven") failed: %v`, err) - } - if got, want := *seven.(*int), 7; got != want { - log.Fatalf("plugin1.Seven=%d, want %d", got, want) - } - - readFunc, err := p.Lookup("ReadCommonX") - if err != nil { - log.Fatalf(`plugin1.Lookup("ReadCommonX") failed: %v`, err) - } - if got := readFunc.(func() int)(); got != wantX { - log.Fatalf("plugin1.ReadCommonX()=%d, want %d", got, wantX) - } - - // sub/plugin1.so is a different plugin with the same name as - // the already loaded plugin. It also depends on common. Test - // that we can load the different plugin, it is actually - // different, and that it sees the same common package. - subpPath, err := filepath.Abs("sub/plugin1.so") - if err != nil { - log.Fatalf("filepath.Abs(%q) failed: %v", subpPath, err) - } - subp, err := plugin.Open(subpPath) - if err != nil { - log.Fatalf("plugin.Open(%q) failed: %v", subpPath, err) - } - - funcVar, err := subp.Lookup("FuncVar") - if err != nil { - log.Fatalf(`sub/plugin1.Lookup("FuncVar") failed: %v`, err) - } - called := false - *funcVar.(*func()) = func() { - called = true - } - - readFunc, err = subp.Lookup("ReadCommonX") - if err != nil { - log.Fatalf(`sub/plugin1.Lookup("ReadCommonX") failed: %v`, err) - } - if got := readFunc.(func() int)(); got != wantX { - log.Fatalf("sub/plugin1.ReadCommonX()=%d, want %d", got, wantX) - } - if !called { - log.Fatal("calling ReadCommonX did not call FuncVar") - } - - subf, err := subp.Lookup("F") - if err != nil { - log.Fatalf(`sub/plugin1.Lookup("F") failed: %v`, err) - } - if gotf := subf.(func() int)(); gotf != 17 { - log.Fatalf(`sub/plugin1.F()=%d, want 17`, gotf) - } - f, err := p.Lookup("F") - if err != nil { - log.Fatalf(`plugin1.Lookup("F") failed: %v`, err) - } - if gotf := f.(func() int)(); gotf != 3 { - log.Fatalf(`plugin1.F()=%d, want 17`, gotf) - } - - p2, err := plugin.Open("plugin2.so") - if err != nil { - log.Fatalf("plugin.Open failed: %v", err) - } - // Check that plugin2's init function was called, and - // that it modifies the same global variable as the host. - if got, want := common.X, 2; got != want { - log.Fatalf("after loading plugin2, common.X=%d, want %d", got, want) - } - - _, err = plugin.Open("plugin2-dup.so") - if err == nil { - log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open should have failed`) - } - if s := err.Error(); !strings.Contains(s, "already loaded") { - log.Fatal(`plugin.Open("plugin2.so"): error does not mention "already loaded"`) - } - - _, err = plugin.Open("plugin-mismatch.so") - if err == nil { - log.Fatal(`plugin.Open("plugin-mismatch.so"): should have failed`) - } - if s := err.Error(); !strings.Contains(s, "different version") { - log.Fatalf(`plugin.Open("plugin-mismatch.so"): error does not mention "different version": %v`, s) - } - - _, err = plugin.Open("plugin2-dup.so") - if err == nil { - log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open after bad plugin should have failed`) - } - _, err = plugin.Open("plugin2.so") - if err != nil { - log.Fatalf(`plugin.Open("plugin2.so"): second open with same name failed: %v`, err) - } - - // Test that unexported types with the same names in - // different plugins do not interfere with each other. - // - // See Issue #21386. - UnexportedNameReuse, _ := p.Lookup("UnexportedNameReuse") - UnexportedNameReuse.(func())() - UnexportedNameReuse, _ = p2.Lookup("UnexportedNameReuse") - UnexportedNameReuse.(func())() - - testUnnamed() - - fmt.Println("PASS") -} diff --git a/libgo/misc/cgo/testplugin/src/iface/main.go b/libgo/misc/cgo/testplugin/src/iface/main.go deleted file mode 100644 index 5e7e4d8..0000000 --- a/libgo/misc/cgo/testplugin/src/iface/main.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "iface_i" - "log" - "plugin" -) - -func main() { - a, err := plugin.Open("iface_a.so") - if err != nil { - log.Fatalf(`plugin.Open("iface_a.so"): %v`, err) - } - b, err := plugin.Open("iface_b.so") - if err != nil { - log.Fatalf(`plugin.Open("iface_b.so"): %v`, err) - } - - af, err := a.Lookup("F") - if err != nil { - log.Fatalf(`a.Lookup("F") failed: %v`, err) - } - bf, err := b.Lookup("F") - if err != nil { - log.Fatalf(`b.Lookup("F") failed: %v`, err) - } - if af.(func() interface{})() != bf.(func() interface{})() { - panic("empty interfaces not equal") - } - - ag, err := a.Lookup("G") - if err != nil { - log.Fatalf(`a.Lookup("G") failed: %v`, err) - } - bg, err := b.Lookup("G") - if err != nil { - log.Fatalf(`b.Lookup("G") failed: %v`, err) - } - if ag.(func() iface_i.I)() != bg.(func() iface_i.I)() { - panic("nonempty interfaces not equal") - } -} diff --git a/libgo/misc/cgo/testplugin/src/iface_a/a.go b/libgo/misc/cgo/testplugin/src/iface_a/a.go deleted file mode 100644 index 29d2e27..0000000 --- a/libgo/misc/cgo/testplugin/src/iface_a/a.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "iface_i" - -//go:noinline -func F() interface{} { - return (*iface_i.T)(nil) -} - -//go:noinline -func G() iface_i.I { - return (*iface_i.T)(nil) -} diff --git a/libgo/misc/cgo/testplugin/src/iface_b/b.go b/libgo/misc/cgo/testplugin/src/iface_b/b.go deleted file mode 100644 index 29d2e27..0000000 --- a/libgo/misc/cgo/testplugin/src/iface_b/b.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "iface_i" - -//go:noinline -func F() interface{} { - return (*iface_i.T)(nil) -} - -//go:noinline -func G() iface_i.I { - return (*iface_i.T)(nil) -} diff --git a/libgo/misc/cgo/testplugin/src/iface_i/i.go b/libgo/misc/cgo/testplugin/src/iface_i/i.go deleted file mode 100644 index 31c8038..0000000 --- a/libgo/misc/cgo/testplugin/src/iface_i/i.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package iface_i - -type I interface { - M() -} - -type T struct { -} - -func (t *T) M() { -} - -// *T implements I diff --git a/libgo/misc/cgo/testplugin/src/issue18584/main.go b/libgo/misc/cgo/testplugin/src/issue18584/main.go deleted file mode 100644 index c280fd4..0000000 --- a/libgo/misc/cgo/testplugin/src/issue18584/main.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "plugin" - -func main() { - p, err := plugin.Open("plugin.so") - if err != nil { - panic(err) - } - - sym, err := p.Lookup("G") - if err != nil { - panic(err) - } - g := sym.(func() bool) - if !g() { - panic("expected types to match, Issue #18584") - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue18584/plugin.go b/libgo/misc/cgo/testplugin/src/issue18584/plugin.go deleted file mode 100644 index be0868d..0000000 --- a/libgo/misc/cgo/testplugin/src/issue18584/plugin.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "reflect" - -type C struct { -} - -func F(c *C) *C { - return nil -} - -func G() bool { - var c *C - return reflect.TypeOf(F).Out(0) == reflect.TypeOf(c) -} diff --git a/libgo/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go b/libgo/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go deleted file mode 100644 index 70fd054..0000000 --- a/libgo/misc/cgo/testplugin/src/issue18676/dynamodbstreamsevt/definition.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dynamodbstreamsevt - -import "encoding/json" - -var foo json.RawMessage - -type Event struct{} - -func (e *Event) Dummy() {} diff --git a/libgo/misc/cgo/testplugin/src/issue18676/main.go b/libgo/misc/cgo/testplugin/src/issue18676/main.go deleted file mode 100644 index c75409d..0000000 --- a/libgo/misc/cgo/testplugin/src/issue18676/main.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// The bug happened like this: -// 1) The main binary adds an itab for *json.UnsupportedValueError / error -// (concrete type / interface type). This itab goes in hash bucket 0x111. -// 2) The plugin adds that same itab again. That makes a cycle in the itab -// chain rooted at hash bucket 0x111. -// 3) The main binary then asks for the itab for *dynamodbstreamsevt.Event / -// json.Unmarshaler. This itab happens to also live in bucket 0x111. -// The lookup code goes into an infinite loop searching for this itab. -// The code is carefully crafted so that the two itabs are both from the -// same bucket, and so that the second itab doesn't exist in -// the itab hashmap yet (so the entire linked list must be searched). -package main - -import ( - "encoding/json" - "issue18676/dynamodbstreamsevt" - "plugin" -) - -func main() { - plugin.Open("plugin.so") - - var x interface{} = (*dynamodbstreamsevt.Event)(nil) - if _, ok := x.(json.Unmarshaler); !ok { - println("something") - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue18676/plugin.go b/libgo/misc/cgo/testplugin/src/issue18676/plugin.go deleted file mode 100644 index 8a3b85a..0000000 --- a/libgo/misc/cgo/testplugin/src/issue18676/plugin.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "C" - -import "issue18676/dynamodbstreamsevt" - -func F(evt *dynamodbstreamsevt.Event) {} diff --git a/libgo/misc/cgo/testplugin/src/issue19418/main.go b/libgo/misc/cgo/testplugin/src/issue19418/main.go deleted file mode 100644 index 2ec9f9a..0000000 --- a/libgo/misc/cgo/testplugin/src/issue19418/main.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "os" - "plugin" -) - -func main() { - p, err := plugin.Open("plugin.so") - if err != nil { - panic(err) - } - - val, err := p.Lookup("Val") - if err != nil { - panic(err) - } - got := *val.(*string) - const want = "linkstr" - if got != want { - fmt.Fprintf(os.Stderr, "issue19418 value is %q, want %q\n", got, want) - os.Exit(2) - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue19418/plugin.go b/libgo/misc/cgo/testplugin/src/issue19418/plugin.go deleted file mode 100644 index fe93b16..0000000 --- a/libgo/misc/cgo/testplugin/src/issue19418/plugin.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -var Val = "val-unset" diff --git a/libgo/misc/cgo/testplugin/src/issue19529/plugin.go b/libgo/misc/cgo/testplugin/src/issue19529/plugin.go deleted file mode 100644 index ad2df6c..0000000 --- a/libgo/misc/cgo/testplugin/src/issue19529/plugin.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "reflect" -) - -type Foo struct { - Bar string `json:"Bar@baz,omitempty"` -} - -func F() { - println(reflect.TypeOf(Foo{}).Field(0).Tag) -} - -func main() {} diff --git a/libgo/misc/cgo/testplugin/src/issue19534/main.go b/libgo/misc/cgo/testplugin/src/issue19534/main.go deleted file mode 100644 index de263b6..0000000 --- a/libgo/misc/cgo/testplugin/src/issue19534/main.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "plugin" - -func main() { - p, err := plugin.Open("plugin.so") - if err != nil { - panic(err) - } - - sym, err := p.Lookup("Foo") - if err != nil { - panic(err) - } - f := sym.(func() int) - if f() != 42 { - panic("expected f() == 42") - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue19534/plugin.go b/libgo/misc/cgo/testplugin/src/issue19534/plugin.go deleted file mode 100644 index 582d333..0000000 --- a/libgo/misc/cgo/testplugin/src/issue19534/plugin.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -func Foo() int { - return 42 -} diff --git a/libgo/misc/cgo/testplugin/src/issue22175/main.go b/libgo/misc/cgo/testplugin/src/issue22175/main.go deleted file mode 100644 index 9be9bab..0000000 --- a/libgo/misc/cgo/testplugin/src/issue22175/main.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "os" - "plugin" -) - -func main() { - p2, err := plugin.Open("issue22175_plugin1.so") - if err != nil { - panic(err) - } - f, err := p2.Lookup("F") - if err != nil { - panic(err) - } - got := f.(func() int)() - const want = 971 - if got != want { - fmt.Fprintf(os.Stderr, "issue22175: F()=%d, want %d", got, want) - os.Exit(1) - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue22175/plugin1.go b/libgo/misc/cgo/testplugin/src/issue22175/plugin1.go deleted file mode 100644 index 5ae6cb6..0000000 --- a/libgo/misc/cgo/testplugin/src/issue22175/plugin1.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "plugin" - -func F() int { - p2, err := plugin.Open("issue22175_plugin2.so") - if err != nil { - panic(err) - } - g, err := p2.Lookup("G") - if err != nil { - panic(err) - } - return g.(func() int)() -} - -func main() {} diff --git a/libgo/misc/cgo/testplugin/src/issue22175/plugin2.go b/libgo/misc/cgo/testplugin/src/issue22175/plugin2.go deleted file mode 100644 index f387a19..0000000 --- a/libgo/misc/cgo/testplugin/src/issue22175/plugin2.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -func G() int { return 971 } - -func main() {} diff --git a/libgo/misc/cgo/testplugin/src/issue22295.pkg/main.go b/libgo/misc/cgo/testplugin/src/issue22295.pkg/main.go deleted file mode 100644 index 6cb186e..0000000 --- a/libgo/misc/cgo/testplugin/src/issue22295.pkg/main.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import ( - "log" - "plugin" -) - -func main() { - p, err := plugin.Open("issue.22295.so") - if err != nil { - log.Fatal(err) - } - f, err := p.Lookup("F") - if err != nil { - log.Fatal(err) - } - const want = 2503 - got := f.(func() int)() - if got != want { - log.Fatalf("got %d, want %d", got, want) - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue22295.pkg/plugin.go b/libgo/misc/cgo/testplugin/src/issue22295.pkg/plugin.go deleted file mode 100644 index 46b08a4..0000000 --- a/libgo/misc/cgo/testplugin/src/issue22295.pkg/plugin.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -var f *int - -func init() { - f = new(int) - *f = 2503 -} - -func F() int { return *f } - -func main() {} diff --git a/libgo/misc/cgo/testplugin/src/issue24351/main.go b/libgo/misc/cgo/testplugin/src/issue24351/main.go deleted file mode 100644 index 4107adf..0000000 --- a/libgo/misc/cgo/testplugin/src/issue24351/main.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "plugin" - -func main() { - p, err := plugin.Open("issue24351.so") - if err != nil { - panic(err) - } - f, err := p.Lookup("B") - if err != nil { - panic(err) - } - c := make(chan bool) - f.(func(chan bool))(c) - <-c -} diff --git a/libgo/misc/cgo/testplugin/src/issue24351/plugin.go b/libgo/misc/cgo/testplugin/src/issue24351/plugin.go deleted file mode 100644 index db17e0a..0000000 --- a/libgo/misc/cgo/testplugin/src/issue24351/plugin.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "fmt" - -func B(c chan bool) { - go func() { - fmt.Println(1.5) - c <- true - }() -} diff --git a/libgo/misc/cgo/testplugin/src/issue25756/main.go b/libgo/misc/cgo/testplugin/src/issue25756/main.go deleted file mode 100644 index 817daf4..0000000 --- a/libgo/misc/cgo/testplugin/src/issue25756/main.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Run the game of life in C using Go for parallelization. - -package main - -import ( - "flag" - "fmt" - "plugin" -) - -const MAXDIM = 100 - -var dim = flag.Int("dim", 16, "board dimensions") -var gen = flag.Int("gen", 10, "generations") - -func main() { - flag.Parse() - - var a [MAXDIM * MAXDIM]int32 - for i := 2; i < *dim; i += 8 { - for j := 2; j < *dim-3; j += 8 { - for y := 0; y < 3; y++ { - a[i**dim+j+y] = 1 - } - } - } - - p, err := plugin.Open("life.so") - if err != nil { - panic(err) - } - f, err := p.Lookup("Run") - if err != nil { - panic(err) - } - f.(func(int, int, int, []int32))(*gen, *dim, *dim, a[:]) - - for i := 0; i < *dim; i++ { - for j := 0; j < *dim; j++ { - if a[i**dim+j] == 0 { - fmt.Print(" ") - } else { - fmt.Print("X") - } - } - fmt.Print("\n") - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue25756/plugin/c-life.c b/libgo/misc/cgo/testplugin/src/issue25756/plugin/c-life.c deleted file mode 100644 index f853163..0000000 --- a/libgo/misc/cgo/testplugin/src/issue25756/plugin/c-life.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include "life.h" -#include "_cgo_export.h" - -const int MYCONST = 0; - -// Do the actual manipulation of the life board in C. This could be -// done easily in Go, we are just using C for demonstration -// purposes. -void -Step(int x, int y, int *a, int *n) -{ - struct GoStart_return r; - - // Use Go to start 4 goroutines each of which handles 1/4 of the - // board. - r = GoStart(0, x, y, 0, x / 2, 0, y / 2, a, n); - assert(r.r0 == 0 && r.r1 == 100); // test multiple returns - r = GoStart(1, x, y, x / 2, x, 0, y / 2, a, n); - assert(r.r0 == 1 && r.r1 == 101); // test multiple returns - GoStart(2, x, y, 0, x / 2, y / 2, y, a, n); - GoStart(3, x, y, x / 2, x, y / 2, y, a, n); - GoWait(0); - GoWait(1); - GoWait(2); - GoWait(3); -} - -// The actual computation. This is called in parallel. -void -DoStep(int xdim, int ydim, int xstart, int xend, int ystart, int yend, int *a, int *n) -{ - int x, y, c, i, j; - - for(x = xstart; x < xend; x++) { - for(y = ystart; y < yend; y++) { - c = 0; - for(i = -1; i <= 1; i++) { - for(j = -1; j <= 1; j++) { - if(x+i >= 0 && x+i < xdim && - y+j >= 0 && y+j < ydim && - (i != 0 || j != 0)) - c += a[(x+i)*xdim + (y+j)] != 0; - } - } - if(c == 3 || (c == 2 && a[x*xdim + y] != 0)) - n[x*xdim + y] = 1; - else - n[x*xdim + y] = 0; - } - } -} diff --git a/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.go b/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.go deleted file mode 100644 index 675a192..0000000 --- a/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// #include "life.h" -import "C" - -import "unsafe" - -func Run(gen, x, y int, a []int32) { - n := make([]int32, x*y) - for i := 0; i < gen; i++ { - C.Step(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&a[0])), (*C.int)(unsafe.Pointer(&n[0]))) - copy(a, n) - } -} - -// Keep the channels visible from Go. -var chans [4]chan bool - -//export GoStart -// Double return value is just for testing. -func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) { - c := make(chan bool, int(C.MYCONST)) - go func() { - C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n) - c <- true - }() - chans[i] = c - return int(i), int(i + 100) -} - -//export GoWait -func GoWait(i C.int) { - <-chans[i] - chans[i] = nil -} diff --git a/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.h b/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.h deleted file mode 100644 index 11d2b97..0000000 --- a/libgo/misc/cgo/testplugin/src/issue25756/plugin/life.h +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -extern void Step(int, int, int *, int *); -extern void DoStep(int, int, int, int, int, int, int *, int *); -extern const int MYCONST; diff --git a/libgo/misc/cgo/testplugin/src/plugin1/plugin1.go b/libgo/misc/cgo/testplugin/src/plugin1/plugin1.go deleted file mode 100644 index 0a9fa2f..0000000 --- a/libgo/misc/cgo/testplugin/src/plugin1/plugin1.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// // No C code required. -import "C" - -import ( - "common" - "reflect" -) - -func F() int { - _ = make([]byte, 1<<21) // trigger stack unwind, Issue #18190. - return 3 -} - -func ReadCommonX() int { - return common.X -} - -var Seven int - -func call(fn func()) { - fn() -} - -func g() { - common.X *= Seven -} - -func init() { - Seven = 7 - call(g) -} - -type sameNameReusedInPlugins struct { - X string -} - -type sameNameHolder struct { - F *sameNameReusedInPlugins -} - -func UnexportedNameReuse() { - h := sameNameHolder{} - v := reflect.ValueOf(&h).Elem().Field(0) - newval := reflect.New(v.Type().Elem()) - v.Set(newval) -} - -func main() { - panic("plugin1.main called") -} diff --git a/libgo/misc/cgo/testplugin/src/plugin2/plugin2.go b/libgo/misc/cgo/testplugin/src/plugin2/plugin2.go deleted file mode 100644 index a67f2de..0000000 --- a/libgo/misc/cgo/testplugin/src/plugin2/plugin2.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -//#include -//#include -import "C" - -// #include -// void cfunc() {} // uses cgo_topofstack - -import ( - "common" - "reflect" - "strings" -) - -func init() { - _ = strings.NewReplacer() // trigger stack unwind, Issue #18190. - C.strerror(C.EIO) // uses cgo_topofstack - common.X = 2 -} - -type sameNameReusedInPlugins struct { - X string -} - -type sameNameHolder struct { - F *sameNameReusedInPlugins -} - -func UnexportedNameReuse() { - h := sameNameHolder{} - v := reflect.ValueOf(&h).Elem().Field(0) - newval := reflect.New(v.Type().Elem()) - v.Set(newval) -} - -func main() { - panic("plugin1.main called") -} diff --git a/libgo/misc/cgo/testplugin/src/sub/plugin1/plugin1.go b/libgo/misc/cgo/testplugin/src/sub/plugin1/plugin1.go deleted file mode 100644 index cf9000c..0000000 --- a/libgo/misc/cgo/testplugin/src/sub/plugin1/plugin1.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// // No C code required. -import "C" - -import "common" - -func F() int { return 17 } - -var FuncVar = func() {} - -func ReadCommonX() int { - FuncVar() - return common.X -} - -func main() { - panic("plugin1.main called") -} diff --git a/libgo/misc/cgo/testplugin/test.bash b/libgo/misc/cgo/testplugin/test.bash deleted file mode 100644 index 1b94bc4..0000000 --- a/libgo/misc/cgo/testplugin/test.bash +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2016 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -set -e - -if [ ! -f src/host/host.go ]; then - cwd=$(pwd) - echo "misc/cgo/testplugin/test.bash is running in $cwd" 1>&2 - exit 1 -fi - -goos=$(go env GOOS) -goarch=$(go env GOARCH) - -function cleanup() { - rm -f plugin*.so unnamed*.so iface*.so life.so issue* - rm -rf host pkg sub iface -} -trap cleanup EXIT - -rm -rf pkg sub -mkdir sub - -GOPATH=$(pwd) go build -i -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin1 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin2 -cp plugin2.so plugin2-dup.so -GOPATH=$(pwd)/altpath go build -gcflags "$GO_GCFLAGS" -buildmode=plugin plugin-mismatch -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=sub/plugin1.so sub/plugin1 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so unnamed1/main.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host - -# test that DWARF sections are emitted for plugins and programs importing "plugin" -if [ $GOOS != "darwin" ]; then - # On macOS, for some reason, the linker doesn't add debug sections to .so, - # see issue #27502. - go run src/checkdwarf/main.go plugin2.so plugin2.UnexportedNameReuse -fi -go run src/checkdwarf/main.go host main.main - -LD_LIBRARY_PATH=$(pwd) ./host - -# Test that types and itabs get properly uniqified. -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin iface_a -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin iface_b -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" iface -LD_LIBRARY_PATH=$(pwd) ./iface - -function _timeout() ( - set -e - $2 & - p=$! - (sleep $1; kill $p 2>/dev/null) & - p2=$! - wait $p 2>/dev/null - kill -0 $p2 2>/dev/null -) - -# Test for issue 18676 - make sure we don't add the same itab twice. -# The buggy code hangs forever, so use a timeout to check for that. -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue18676/plugin.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue18676 src/issue18676/main.go -_timeout 10s ./issue18676 - -# Test for issue 19534 - that we can load a plugin built in a path with non-alpha -# characters -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -ldflags='-pluginpath=issue.19534' -o plugin.so src/issue19534/plugin.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue19534 src/issue19534/main.go -./issue19534 - -# Test for issue 18584 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue18584/plugin.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue18584 src/issue18584/main.go -./issue18584 - -# Test for issue 19418 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin "-ldflags=-X main.Val=linkstr" -o plugin.so src/issue19418/plugin.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue19418 src/issue19418/main.go -./issue19418 - -# Test for issue 19529 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue19529/plugin.go - -# Test for issue 22175 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin1.so src/issue22175/plugin1.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin2.so src/issue22175/plugin2.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.go -./issue22175 - -# Test for issue 22295 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go -./issue22295 - -# Test for issue 24351 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go -./issue24351 - -# Test for issue 25756 -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o life.so issue25756/plugin -GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue25756 src/issue25756/main.go -# Fails intermittently, but 20 runs should cause the failure -for i in `seq 1 20`; -do - ./issue25756 > /dev/null -done diff --git a/libgo/misc/cgo/testplugin/testdata/checkdwarf/main.go b/libgo/misc/cgo/testplugin/testdata/checkdwarf/main.go new file mode 100644 index 0000000..7886c83 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/checkdwarf/main.go @@ -0,0 +1,106 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Usage: +// +// checkdwarf +// +// Opens , which must be an executable or a library and checks that +// there is an entry in .debug_info whose name ends in + +package main + +import ( + "debug/dwarf" + "debug/elf" + "debug/macho" + "debug/pe" + "fmt" + "os" + "strings" +) + +func usage() { + fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n") +} + +type dwarfer interface { + DWARF() (*dwarf.Data, error) +} + +func openElf(path string) dwarfer { + exe, err := elf.Open(path) + if err != nil { + return nil + } + return exe +} + +func openMacho(path string) dwarfer { + exe, err := macho.Open(path) + if err != nil { + return nil + } + return exe +} + +func openPE(path string) dwarfer { + exe, err := pe.Open(path) + if err != nil { + return nil + } + return exe +} + +func main() { + if len(os.Args) != 3 { + usage() + } + + exePath := os.Args[1] + dieSuffix := os.Args[2] + + var exe dwarfer + + for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} { + exe = openfn(exePath) + if exe != nil { + break + } + } + + if exe == nil { + fmt.Fprintf(os.Stderr, "could not open %s\n", exePath) + os.Exit(1) + } + + data, err := exe.DWARF() + if err != nil { + fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err) + os.Exit(1) + } + + rdr := data.Reader() + for { + e, err := rdr.Next() + if err != nil { + fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err) + os.Exit(1) + } + if e == nil { + break + } + name, hasname := e.Val(dwarf.AttrName).(string) + if !hasname { + continue + } + if strings.HasSuffix(name, dieSuffix) { + // found + os.Exit(0) + } + } + + fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix) + os.Exit(1) +} diff --git a/libgo/misc/cgo/testplugin/testdata/common/common.go b/libgo/misc/cgo/testplugin/testdata/common/common.go new file mode 100644 index 0000000..b064e6b --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/common/common.go @@ -0,0 +1,11 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package common + +var X int + +func init() { + X = 3 +} diff --git a/libgo/misc/cgo/testplugin/testdata/host/host.go b/libgo/misc/cgo/testplugin/testdata/host/host.go new file mode 100644 index 0000000..a379932 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/host/host.go @@ -0,0 +1,176 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "log" + "path/filepath" + "plugin" + "strings" + + "testplugin/common" +) + +func init() { + common.X *= 5 +} + +// testUnnamed tests that two plugins built with .go files passed on +// the command line do not have overlapping symbols. That is, +// unnamed1.so/FuncInt and unnamed2.so/FuncInt should be distinct functions. +func testUnnamed() { + p, err := plugin.Open("unnamed1.so") + if err != nil { + log.Fatalf(`plugin.Open("unnamed1.so"): %v`, err) + } + fn, err := p.Lookup("FuncInt") + if err != nil { + log.Fatalf(`unnamed1.so: Lookup("FuncInt") failed: %v`, err) + } + if got, want := fn.(func() int)(), 1; got != want { + log.Fatalf("unnamed1.so: FuncInt()=%d, want %d", got, want) + } + + p, err = plugin.Open("unnamed2.so") + if err != nil { + log.Fatalf(`plugin.Open("unnamed2.so"): %v`, err) + } + fn, err = p.Lookup("FuncInt") + if err != nil { + log.Fatalf(`unnamed2.so: Lookup("FuncInt") failed: %v`, err) + } + if got, want := fn.(func() int)(), 2; got != want { + log.Fatalf("unnamed2.so: FuncInt()=%d, want %d", got, want) + } +} + +func main() { + if got, want := common.X, 3*5; got != want { + log.Fatalf("before plugin load common.X=%d, want %d", got, want) + } + + p, err := plugin.Open("plugin1.so") + if err != nil { + log.Fatalf("plugin.Open failed: %v", err) + } + + const wantX = 3 * 5 * 7 + if got := common.X; got != wantX { + log.Fatalf("after plugin load common.X=%d, want %d", got, wantX) + } + + seven, err := p.Lookup("Seven") + if err != nil { + log.Fatalf(`Lookup("Seven") failed: %v`, err) + } + if got, want := *seven.(*int), 7; got != want { + log.Fatalf("plugin1.Seven=%d, want %d", got, want) + } + + readFunc, err := p.Lookup("ReadCommonX") + if err != nil { + log.Fatalf(`plugin1.Lookup("ReadCommonX") failed: %v`, err) + } + if got := readFunc.(func() int)(); got != wantX { + log.Fatalf("plugin1.ReadCommonX()=%d, want %d", got, wantX) + } + + // sub/plugin1.so is a different plugin with the same name as + // the already loaded plugin. It also depends on common. Test + // that we can load the different plugin, it is actually + // different, and that it sees the same common package. + subpPath, err := filepath.Abs("sub/plugin1.so") + if err != nil { + log.Fatalf("filepath.Abs(%q) failed: %v", subpPath, err) + } + subp, err := plugin.Open(subpPath) + if err != nil { + log.Fatalf("plugin.Open(%q) failed: %v", subpPath, err) + } + + funcVar, err := subp.Lookup("FuncVar") + if err != nil { + log.Fatalf(`sub/plugin1.Lookup("FuncVar") failed: %v`, err) + } + called := false + *funcVar.(*func()) = func() { + called = true + } + + readFunc, err = subp.Lookup("ReadCommonX") + if err != nil { + log.Fatalf(`sub/plugin1.Lookup("ReadCommonX") failed: %v`, err) + } + if got := readFunc.(func() int)(); got != wantX { + log.Fatalf("sub/plugin1.ReadCommonX()=%d, want %d", got, wantX) + } + if !called { + log.Fatal("calling ReadCommonX did not call FuncVar") + } + + subf, err := subp.Lookup("F") + if err != nil { + log.Fatalf(`sub/plugin1.Lookup("F") failed: %v`, err) + } + if gotf := subf.(func() int)(); gotf != 17 { + log.Fatalf(`sub/plugin1.F()=%d, want 17`, gotf) + } + f, err := p.Lookup("F") + if err != nil { + log.Fatalf(`plugin1.Lookup("F") failed: %v`, err) + } + if gotf := f.(func() int)(); gotf != 3 { + log.Fatalf(`plugin1.F()=%d, want 17`, gotf) + } + + p2, err := plugin.Open("plugin2.so") + if err != nil { + log.Fatalf("plugin.Open failed: %v", err) + } + // Check that plugin2's init function was called, and + // that it modifies the same global variable as the host. + if got, want := common.X, 2; got != want { + log.Fatalf("after loading plugin2, common.X=%d, want %d", got, want) + } + + _, err = plugin.Open("plugin2-dup.so") + if err == nil { + log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open should have failed`) + } + if s := err.Error(); !strings.Contains(s, "already loaded") { + log.Fatal(`plugin.Open("plugin2.so"): error does not mention "already loaded"`) + } + + _, err = plugin.Open("plugin-mismatch.so") + if err == nil { + log.Fatal(`plugin.Open("plugin-mismatch.so"): should have failed`) + } + if s := err.Error(); !strings.Contains(s, "different version") { + log.Fatalf(`plugin.Open("plugin-mismatch.so"): error does not mention "different version": %v`, s) + } + + _, err = plugin.Open("plugin2-dup.so") + if err == nil { + log.Fatal(`plugin.Open("plugin2-dup.so"): duplicate open after bad plugin should have failed`) + } + _, err = plugin.Open("plugin2.so") + if err != nil { + log.Fatalf(`plugin.Open("plugin2.so"): second open with same name failed: %v`, err) + } + + // Test that unexported types with the same names in + // different plugins do not interfere with each other. + // + // See Issue #21386. + UnexportedNameReuse, _ := p.Lookup("UnexportedNameReuse") + UnexportedNameReuse.(func())() + UnexportedNameReuse, _ = p2.Lookup("UnexportedNameReuse") + UnexportedNameReuse.(func())() + + testUnnamed() + + fmt.Println("PASS") +} diff --git a/libgo/misc/cgo/testplugin/testdata/iface/main.go b/libgo/misc/cgo/testplugin/testdata/iface/main.go new file mode 100644 index 0000000..c04f288 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/iface/main.go @@ -0,0 +1,47 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "log" + "plugin" + + "testplugin/iface_i" +) + +func main() { + a, err := plugin.Open("iface_a.so") + if err != nil { + log.Fatalf(`plugin.Open("iface_a.so"): %v`, err) + } + b, err := plugin.Open("iface_b.so") + if err != nil { + log.Fatalf(`plugin.Open("iface_b.so"): %v`, err) + } + + af, err := a.Lookup("F") + if err != nil { + log.Fatalf(`a.Lookup("F") failed: %v`, err) + } + bf, err := b.Lookup("F") + if err != nil { + log.Fatalf(`b.Lookup("F") failed: %v`, err) + } + if af.(func() interface{})() != bf.(func() interface{})() { + panic("empty interfaces not equal") + } + + ag, err := a.Lookup("G") + if err != nil { + log.Fatalf(`a.Lookup("G") failed: %v`, err) + } + bg, err := b.Lookup("G") + if err != nil { + log.Fatalf(`b.Lookup("G") failed: %v`, err) + } + if ag.(func() iface_i.I)() != bg.(func() iface_i.I)() { + panic("nonempty interfaces not equal") + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/iface_a/a.go b/libgo/misc/cgo/testplugin/testdata/iface_a/a.go new file mode 100644 index 0000000..357f7e8 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/iface_a/a.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "testplugin/iface_i" + +//go:noinline +func F() interface{} { + return (*iface_i.T)(nil) +} + +//go:noinline +func G() iface_i.I { + return (*iface_i.T)(nil) +} diff --git a/libgo/misc/cgo/testplugin/testdata/iface_b/b.go b/libgo/misc/cgo/testplugin/testdata/iface_b/b.go new file mode 100644 index 0000000..357f7e8 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/iface_b/b.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "testplugin/iface_i" + +//go:noinline +func F() interface{} { + return (*iface_i.T)(nil) +} + +//go:noinline +func G() iface_i.I { + return (*iface_i.T)(nil) +} diff --git a/libgo/misc/cgo/testplugin/testdata/iface_i/i.go b/libgo/misc/cgo/testplugin/testdata/iface_i/i.go new file mode 100644 index 0000000..31c8038 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/iface_i/i.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iface_i + +type I interface { + M() +} + +type T struct { +} + +func (t *T) M() { +} + +// *T implements I diff --git a/libgo/misc/cgo/testplugin/testdata/issue18584/main.go b/libgo/misc/cgo/testplugin/testdata/issue18584/main.go new file mode 100644 index 0000000..c280fd4 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue18584/main.go @@ -0,0 +1,23 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "plugin" + +func main() { + p, err := plugin.Open("plugin.so") + if err != nil { + panic(err) + } + + sym, err := p.Lookup("G") + if err != nil { + panic(err) + } + g := sym.(func() bool) + if !g() { + panic("expected types to match, Issue #18584") + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue18584/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue18584/plugin.go new file mode 100644 index 0000000..be0868d --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue18584/plugin.go @@ -0,0 +1,19 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "reflect" + +type C struct { +} + +func F(c *C) *C { + return nil +} + +func G() bool { + var c *C + return reflect.TypeOf(F).Out(0) == reflect.TypeOf(c) +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue18676/dynamodbstreamsevt/definition.go b/libgo/misc/cgo/testplugin/testdata/issue18676/dynamodbstreamsevt/definition.go new file mode 100644 index 0000000..70fd054 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue18676/dynamodbstreamsevt/definition.go @@ -0,0 +1,13 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dynamodbstreamsevt + +import "encoding/json" + +var foo json.RawMessage + +type Event struct{} + +func (e *Event) Dummy() {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue18676/main.go b/libgo/misc/cgo/testplugin/testdata/issue18676/main.go new file mode 100644 index 0000000..b1dadbe --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue18676/main.go @@ -0,0 +1,31 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The bug happened like this: +// 1) The main binary adds an itab for *json.UnsupportedValueError / error +// (concrete type / interface type). This itab goes in hash bucket 0x111. +// 2) The plugin adds that same itab again. That makes a cycle in the itab +// chain rooted at hash bucket 0x111. +// 3) The main binary then asks for the itab for *dynamodbstreamsevt.Event / +// json.Unmarshaler. This itab happens to also live in bucket 0x111. +// The lookup code goes into an infinite loop searching for this itab. +// The code is carefully crafted so that the two itabs are both from the +// same bucket, and so that the second itab doesn't exist in +// the itab hashmap yet (so the entire linked list must be searched). +package main + +import ( + "encoding/json" + "plugin" + "testplugin/issue18676/dynamodbstreamsevt" +) + +func main() { + plugin.Open("plugin.so") + + var x interface{} = (*dynamodbstreamsevt.Event)(nil) + if _, ok := x.(json.Unmarshaler); !ok { + println("something") + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue18676/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue18676/plugin.go new file mode 100644 index 0000000..e7fc74f --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue18676/plugin.go @@ -0,0 +1,11 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +import "testplugin/issue18676/dynamodbstreamsevt" + +func F(evt *dynamodbstreamsevt.Event) {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue19418/main.go b/libgo/misc/cgo/testplugin/testdata/issue19418/main.go new file mode 100644 index 0000000..2ec9f9a --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue19418/main.go @@ -0,0 +1,29 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "os" + "plugin" +) + +func main() { + p, err := plugin.Open("plugin.so") + if err != nil { + panic(err) + } + + val, err := p.Lookup("Val") + if err != nil { + panic(err) + } + got := *val.(*string) + const want = "linkstr" + if got != want { + fmt.Fprintf(os.Stderr, "issue19418 value is %q, want %q\n", got, want) + os.Exit(2) + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue19418/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue19418/plugin.go new file mode 100644 index 0000000..fe93b16 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue19418/plugin.go @@ -0,0 +1,7 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +var Val = "val-unset" diff --git a/libgo/misc/cgo/testplugin/testdata/issue19529/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue19529/plugin.go new file mode 100644 index 0000000..ad2df6c --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue19529/plugin.go @@ -0,0 +1,15 @@ +package main + +import ( + "reflect" +) + +type Foo struct { + Bar string `json:"Bar@baz,omitempty"` +} + +func F() { + println(reflect.TypeOf(Foo{}).Field(0).Tag) +} + +func main() {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue19534/main.go b/libgo/misc/cgo/testplugin/testdata/issue19534/main.go new file mode 100644 index 0000000..de263b6 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue19534/main.go @@ -0,0 +1,23 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "plugin" + +func main() { + p, err := plugin.Open("plugin.so") + if err != nil { + panic(err) + } + + sym, err := p.Lookup("Foo") + if err != nil { + panic(err) + } + f := sym.(func() int) + if f() != 42 { + panic("expected f() == 42") + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue19534/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue19534/plugin.go new file mode 100644 index 0000000..582d333 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue19534/plugin.go @@ -0,0 +1,9 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +func Foo() int { + return 42 +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue22175/main.go b/libgo/misc/cgo/testplugin/testdata/issue22175/main.go new file mode 100644 index 0000000..9be9bab --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue22175/main.go @@ -0,0 +1,28 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "os" + "plugin" +) + +func main() { + p2, err := plugin.Open("issue22175_plugin1.so") + if err != nil { + panic(err) + } + f, err := p2.Lookup("F") + if err != nil { + panic(err) + } + got := f.(func() int)() + const want = 971 + if got != want { + fmt.Fprintf(os.Stderr, "issue22175: F()=%d, want %d", got, want) + os.Exit(1) + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue22175/plugin1.go b/libgo/misc/cgo/testplugin/testdata/issue22175/plugin1.go new file mode 100644 index 0000000..5ae6cb6 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue22175/plugin1.go @@ -0,0 +1,21 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "plugin" + +func F() int { + p2, err := plugin.Open("issue22175_plugin2.so") + if err != nil { + panic(err) + } + g, err := p2.Lookup("G") + if err != nil { + panic(err) + } + return g.(func() int)() +} + +func main() {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue22175/plugin2.go b/libgo/misc/cgo/testplugin/testdata/issue22175/plugin2.go new file mode 100644 index 0000000..f387a19 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue22175/plugin2.go @@ -0,0 +1,9 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +func G() int { return 971 } + +func main() {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/main.go b/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/main.go new file mode 100644 index 0000000..6cb186e --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/main.go @@ -0,0 +1,28 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import ( + "log" + "plugin" +) + +func main() { + p, err := plugin.Open("issue.22295.so") + if err != nil { + log.Fatal(err) + } + f, err := p.Lookup("F") + if err != nil { + log.Fatal(err) + } + const want = 2503 + got := f.(func() int)() + if got != want { + log.Fatalf("got %d, want %d", got, want) + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/plugin.go new file mode 100644 index 0000000..46b08a4 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue22295.pkg/plugin.go @@ -0,0 +1,16 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +var f *int + +func init() { + f = new(int) + *f = 2503 +} + +func F() int { return *f } + +func main() {} diff --git a/libgo/misc/cgo/testplugin/testdata/issue24351/main.go b/libgo/misc/cgo/testplugin/testdata/issue24351/main.go new file mode 100644 index 0000000..4107adf --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue24351/main.go @@ -0,0 +1,21 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "plugin" + +func main() { + p, err := plugin.Open("issue24351.so") + if err != nil { + panic(err) + } + f, err := p.Lookup("B") + if err != nil { + panic(err) + } + c := make(chan bool) + f.(func(chan bool))(c) + <-c +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue24351/plugin.go b/libgo/misc/cgo/testplugin/testdata/issue24351/plugin.go new file mode 100644 index 0000000..db17e0a --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue24351/plugin.go @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "fmt" + +func B(c chan bool) { + go func() { + fmt.Println(1.5) + c <- true + }() +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue25756/main.go b/libgo/misc/cgo/testplugin/testdata/issue25756/main.go new file mode 100644 index 0000000..817daf4 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue25756/main.go @@ -0,0 +1,52 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Run the game of life in C using Go for parallelization. + +package main + +import ( + "flag" + "fmt" + "plugin" +) + +const MAXDIM = 100 + +var dim = flag.Int("dim", 16, "board dimensions") +var gen = flag.Int("gen", 10, "generations") + +func main() { + flag.Parse() + + var a [MAXDIM * MAXDIM]int32 + for i := 2; i < *dim; i += 8 { + for j := 2; j < *dim-3; j += 8 { + for y := 0; y < 3; y++ { + a[i**dim+j+y] = 1 + } + } + } + + p, err := plugin.Open("life.so") + if err != nil { + panic(err) + } + f, err := p.Lookup("Run") + if err != nil { + panic(err) + } + f.(func(int, int, int, []int32))(*gen, *dim, *dim, a[:]) + + for i := 0; i < *dim; i++ { + for j := 0; j < *dim; j++ { + if a[i**dim+j] == 0 { + fmt.Print(" ") + } else { + fmt.Print("X") + } + } + fmt.Print("\n") + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/c-life.c b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/c-life.c new file mode 100644 index 0000000..f853163 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/c-life.c @@ -0,0 +1,56 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include +#include "life.h" +#include "_cgo_export.h" + +const int MYCONST = 0; + +// Do the actual manipulation of the life board in C. This could be +// done easily in Go, we are just using C for demonstration +// purposes. +void +Step(int x, int y, int *a, int *n) +{ + struct GoStart_return r; + + // Use Go to start 4 goroutines each of which handles 1/4 of the + // board. + r = GoStart(0, x, y, 0, x / 2, 0, y / 2, a, n); + assert(r.r0 == 0 && r.r1 == 100); // test multiple returns + r = GoStart(1, x, y, x / 2, x, 0, y / 2, a, n); + assert(r.r0 == 1 && r.r1 == 101); // test multiple returns + GoStart(2, x, y, 0, x / 2, y / 2, y, a, n); + GoStart(3, x, y, x / 2, x, y / 2, y, a, n); + GoWait(0); + GoWait(1); + GoWait(2); + GoWait(3); +} + +// The actual computation. This is called in parallel. +void +DoStep(int xdim, int ydim, int xstart, int xend, int ystart, int yend, int *a, int *n) +{ + int x, y, c, i, j; + + for(x = xstart; x < xend; x++) { + for(y = ystart; y < yend; y++) { + c = 0; + for(i = -1; i <= 1; i++) { + for(j = -1; j <= 1; j++) { + if(x+i >= 0 && x+i < xdim && + y+j >= 0 && y+j < ydim && + (i != 0 || j != 0)) + c += a[(x+i)*xdim + (y+j)] != 0; + } + } + if(c == 3 || (c == 2 && a[x*xdim + y] != 0)) + n[x*xdim + y] = 1; + else + n[x*xdim + y] = 0; + } + } +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.go b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.go new file mode 100644 index 0000000..675a192 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.go @@ -0,0 +1,39 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// #include "life.h" +import "C" + +import "unsafe" + +func Run(gen, x, y int, a []int32) { + n := make([]int32, x*y) + for i := 0; i < gen; i++ { + C.Step(C.int(x), C.int(y), (*C.int)(unsafe.Pointer(&a[0])), (*C.int)(unsafe.Pointer(&n[0]))) + copy(a, n) + } +} + +// Keep the channels visible from Go. +var chans [4]chan bool + +//export GoStart +// Double return value is just for testing. +func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) { + c := make(chan bool, int(C.MYCONST)) + go func() { + C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n) + c <- true + }() + chans[i] = c + return int(i), int(i + 100) +} + +//export GoWait +func GoWait(i C.int) { + <-chans[i] + chans[i] = nil +} diff --git a/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.h b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.h new file mode 100644 index 0000000..11d2b97 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/issue25756/plugin/life.h @@ -0,0 +1,7 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +extern void Step(int, int, int *, int *); +extern void DoStep(int, int, int, int, int, int, int *, int *); +extern const int MYCONST; diff --git a/libgo/misc/cgo/testplugin/testdata/plugin1/plugin1.go b/libgo/misc/cgo/testplugin/testdata/plugin1/plugin1.go new file mode 100644 index 0000000..d29d674 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/plugin1/plugin1.go @@ -0,0 +1,57 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// // No C code required. +import "C" + +import ( + "reflect" + + "testplugin/common" +) + +func F() int { + _ = make([]byte, 1<<21) // trigger stack unwind, Issue #18190. + return 3 +} + +func ReadCommonX() int { + return common.X +} + +var Seven int + +func call(fn func()) { + fn() +} + +func g() { + common.X *= Seven +} + +func init() { + Seven = 7 + call(g) +} + +type sameNameReusedInPlugins struct { + X string +} + +type sameNameHolder struct { + F *sameNameReusedInPlugins +} + +func UnexportedNameReuse() { + h := sameNameHolder{} + v := reflect.ValueOf(&h).Elem().Field(0) + newval := reflect.New(v.Type().Elem()) + v.Set(newval) +} + +func main() { + panic("plugin1.main called") +} diff --git a/libgo/misc/cgo/testplugin/testdata/plugin2/plugin2.go b/libgo/misc/cgo/testplugin/testdata/plugin2/plugin2.go new file mode 100644 index 0000000..31ed642 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/plugin2/plugin2.go @@ -0,0 +1,44 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +//#include +//#include +import "C" + +// #include +// void cfunc() {} // uses cgo_topofstack + +import ( + "reflect" + "strings" + + "testplugin/common" +) + +func init() { + _ = strings.NewReplacer() // trigger stack unwind, Issue #18190. + C.strerror(C.EIO) // uses cgo_topofstack + common.X = 2 +} + +type sameNameReusedInPlugins struct { + X string +} + +type sameNameHolder struct { + F *sameNameReusedInPlugins +} + +func UnexportedNameReuse() { + h := sameNameHolder{} + v := reflect.ValueOf(&h).Elem().Field(0) + newval := reflect.New(v.Type().Elem()) + v.Set(newval) +} + +func main() { + panic("plugin1.main called") +} diff --git a/libgo/misc/cgo/testplugin/testdata/sub/plugin1/plugin1.go b/libgo/misc/cgo/testplugin/testdata/sub/plugin1/plugin1.go new file mode 100644 index 0000000..5f891b0 --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/sub/plugin1/plugin1.go @@ -0,0 +1,23 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// // No C code required. +import "C" + +import "testplugin/common" + +func F() int { return 17 } + +var FuncVar = func() {} + +func ReadCommonX() int { + FuncVar() + return common.X +} + +func main() { + panic("plugin1.main called") +} diff --git a/libgo/misc/cgo/testplugin/testdata/unnamed1/main.go b/libgo/misc/cgo/testplugin/testdata/unnamed1/main.go new file mode 100644 index 0000000..dd1777b --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/unnamed1/main.go @@ -0,0 +1,25 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +// // No C code required. +import "C" + +func FuncInt() int { return 1 } + +// Add a recursive type to check that type equality across plugins doesn't +// crash. See https://golang.org/issues/19258 +func FuncRecursive() X { return X{} } + +type Y struct { + X *X +} +type X struct { + Y Y +} + +func main() {} diff --git a/libgo/misc/cgo/testplugin/testdata/unnamed2/main.go b/libgo/misc/cgo/testplugin/testdata/unnamed2/main.go new file mode 100644 index 0000000..757436f --- /dev/null +++ b/libgo/misc/cgo/testplugin/testdata/unnamed2/main.go @@ -0,0 +1,23 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +// // No C code required. +import "C" + +func FuncInt() int { return 2 } + +func FuncRecursive() X { return X{} } + +type Y struct { + X *X +} +type X struct { + Y Y +} + +func main() {} diff --git a/libgo/misc/cgo/testplugin/unnamed1/main.go b/libgo/misc/cgo/testplugin/unnamed1/main.go deleted file mode 100644 index caf09c9..0000000 --- a/libgo/misc/cgo/testplugin/unnamed1/main.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// // No C code required. -import "C" - -func FuncInt() int { return 1 } - -// Add a recursive type to check that type equality across plugins doesn't -// crash. See https://golang.org/issues/19258 -func FuncRecursive() X { return X{} } - -type Y struct { - X *X -} -type X struct { - Y Y -} - -func main() {} diff --git a/libgo/misc/cgo/testplugin/unnamed2/main.go b/libgo/misc/cgo/testplugin/unnamed2/main.go deleted file mode 100644 index 7ef6610..0000000 --- a/libgo/misc/cgo/testplugin/unnamed2/main.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// // No C code required. -import "C" - -func FuncInt() int { return 2 } - -func FuncRecursive() X { return X{} } - -type Y struct { - X *X -} -type X struct { - Y Y -} - -func main() {} diff --git a/libgo/misc/cgo/testsanitizers/cc_test.go b/libgo/misc/cgo/testsanitizers/cc_test.go index 218e225..0192a66 100644 --- a/libgo/misc/cgo/testsanitizers/cc_test.go +++ b/libgo/misc/cgo/testsanitizers/cc_test.go @@ -394,7 +394,7 @@ func (c *config) checkRuntime() (skip bool, err error) { // srcPath returns the path to the given file relative to this test's source tree. func srcPath(path string) string { - return filepath.Join("src", path) + return filepath.Join("testdata", path) } // A tempDir manages a temporary directory within a test. diff --git a/libgo/misc/cgo/testsanitizers/src/msan.go b/libgo/misc/cgo/testsanitizers/src/msan.go deleted file mode 100644 index 7915fa8..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#include - -void f(int32_t *p, int n) { - int i; - - for (i = 0; i < n; i++) { - p[i] = (int32_t)i; - } -} -*/ -import "C" - -import ( - "fmt" - "os" - "unsafe" -) - -func main() { - a := make([]int32, 10) - C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) - for i, v := range a { - if i != int(v) { - fmt.Println("bad %d: %v\n", i, a) - os.Exit(1) - } - } -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan2.go b/libgo/misc/cgo/testsanitizers/src/msan2.go deleted file mode 100644 index 6690cb0..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan2.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#include -#include -#include - -void f(int32_t *p, int n) { - int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); - memcpy(p, q, n * sizeof(*p)); - free(q); -} - -void g(int32_t *p, int n) { - if (p[4] != 1) { - abort(); - } -} -*/ -import "C" - -import ( - "unsafe" -) - -func main() { - a := make([]int32, 10) - C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) - a[4] = 1 - C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan2_cmsan.go b/libgo/misc/cgo/testsanitizers/src/msan2_cmsan.go deleted file mode 100644 index 8fdaea9..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan2_cmsan.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#cgo LDFLAGS: -fsanitize=memory -#cgo CPPFLAGS: -fsanitize=memory - -#include -#include -#include - -void f(int32_t *p, int n) { - int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); - memcpy(p, q, n * sizeof(*p)); - free(q); -} - -void g(int32_t *p, int n) { - if (p[4] != 1) { - abort(); - } -} -*/ -import "C" - -import ( - "unsafe" -) - -func main() { - a := make([]int32, 10) - C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) - a[4] = 1 - C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan3.go b/libgo/misc/cgo/testsanitizers/src/msan3.go deleted file mode 100644 index 61a9c29..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan3.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -extern int *GoFn(int *); - -// Yes, you can have definitions if you use //export, as long as they are weak. -int f(void) __attribute__ ((weak)); - -int f() { - int i; - int *p = GoFn(&i); - if (*p != 12345) - return 0; - return 1; -} -*/ -import "C" - -//export GoFn -func GoFn(p *C.int) *C.int { - *p = C.int(12345) - return p -} - -func main() { - if r := C.f(); r != 1 { - panic(r) - } -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan4.go b/libgo/misc/cgo/testsanitizers/src/msan4.go deleted file mode 100644 index 6c91ff5..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan4.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// The memory profiler can call copy from a slice on the system stack, -// which msan used to think meant a reference to uninitialized memory. - -/* -#include -#include - -extern void Nop(char*); - -// Use weak as a hack to permit defining a function even though we use export. -void poison() __attribute__ ((weak)); - -// Poison the stack. -void poison() { - char a[1024]; - Nop(&a[0]); -} - -*/ -import "C" - -import ( - "runtime" -) - -func main() { - runtime.MemProfileRate = 1 - start(100) -} - -func start(i int) { - if i == 0 { - return - } - C.poison() - // Tie up a thread. - // We won't actually wait for this sleep to complete. - go func() { C.sleep(1) }() - start(i - 1) -} - -//export Nop -func Nop(*C.char) { -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan5.go b/libgo/misc/cgo/testsanitizers/src/msan5.go deleted file mode 100644 index f1479eb..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan5.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Using reflect to set a value was not seen by msan. - -/* -#include - -extern void Go1(int*); -extern void Go2(char*); - -// Use weak as a hack to permit defining a function even though we use export. -void C1() __attribute__ ((weak)); -void C2() __attribute__ ((weak)); - -void C1() { - int i; - Go1(&i); - if (i != 42) { - abort(); - } -} - -void C2() { - char a[2]; - a[1] = 42; - Go2(a); - if (a[0] != 42) { - abort(); - } -} -*/ -import "C" - -import ( - "reflect" - "unsafe" -) - -//export Go1 -func Go1(p *C.int) { - reflect.ValueOf(p).Elem().Set(reflect.ValueOf(C.int(42))) -} - -//export Go2 -func Go2(p *C.char) { - a := (*[2]byte)(unsafe.Pointer(p)) - reflect.Copy(reflect.ValueOf(a[:1]), reflect.ValueOf(a[1:])) -} - -func main() { - C.C1() - C.C2() -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan6.go b/libgo/misc/cgo/testsanitizers/src/msan6.go deleted file mode 100644 index 003989c..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan6.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// A C function returning a value on the Go stack could leave the Go -// stack marked as uninitialized, potentially causing a later error -// when the stack is used for something else. Issue 26209. - -/* -#cgo LDFLAGS: -fsanitize=memory -#cgo CPPFLAGS: -fsanitize=memory - -#include -#include -#include - -typedef struct { - uintptr_t a[20]; -} S; - -S f() { - S *p; - - p = (S *)(malloc(sizeof(S))); - p->a[0] = 0; - return *p; -} -*/ -import "C" - -// allocateStack extends the stack so that stack copying doesn't -// confuse the msan data structures. -//go:noinline -func allocateStack(i int) int { - if i == 0 { - return i - } - return allocateStack(i - 1) -} - -// F1 marks a chunk of stack as uninitialized. -// C.f returns an uninitialized struct on the stack, so msan will mark -// the stack as uninitialized. -//go:noinline -func F1() uintptr { - s := C.f() - return uintptr(s.a[0]) -} - -// F2 allocates a struct on the stack and converts it to an empty interface, -// which will call msanread and see that the data appears uninitialized. -//go:noinline -func F2() interface{} { - return C.S{} -} - -func poisonStack(i int) int { - if i == 0 { - return int(F1()) - } - F1() - r := poisonStack(i - 1) - F2() - return r -} - -func main() { - allocateStack(16384) - poisonStack(128) -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan_fail.go b/libgo/misc/cgo/testsanitizers/src/msan_fail.go deleted file mode 100644 index 4c8dab3..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan_fail.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -/* -#include -#include -#include - -void f(int32_t *p, int n) { - int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); - memcpy(p, q, n * sizeof(*p)); - free(q); -} - -void g(int32_t *p, int n) { - if (p[4] != 1) { - // We shouldn't get here; msan should stop us first. - exit(0); - } -} -*/ -import "C" - -import ( - "unsafe" -) - -func main() { - a := make([]int32, 10) - C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) - a[3] = 1 - C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) -} diff --git a/libgo/misc/cgo/testsanitizers/src/msan_shared.go b/libgo/misc/cgo/testsanitizers/src/msan_shared.go deleted file mode 100644 index 966947c..0000000 --- a/libgo/misc/cgo/testsanitizers/src/msan_shared.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This program segfaulted during libpreinit when built with -msan: -// http://golang.org/issue/18707 - -package main - -import "C" - -func main() {} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan.go b/libgo/misc/cgo/testsanitizers/src/tsan.go deleted file mode 100644 index 6c377a7..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program produced false race reports when run under the C/C++ -// ThreadSanitizer, as it did not understand the synchronization in -// the Go code. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -int val; - -int getVal() { - return val; -} - -void setVal(int i) { - val = i; -} -*/ -import "C" - -import ( - "runtime" -) - -func main() { - runtime.LockOSThread() - C.setVal(1) - c := make(chan bool) - go func() { - runtime.LockOSThread() - C.setVal(2) - c <- true - }() - <-c - if v := C.getVal(); v != 2 { - panic(v) - } -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan10.go b/libgo/misc/cgo/testsanitizers/src/tsan10.go deleted file mode 100644 index a40f245..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan10.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program hung when run under the C/C++ ThreadSanitizer. -// TSAN defers asynchronous signals until the signaled thread calls into libc. -// Since the Go runtime makes direct futex syscalls, Go runtime threads could -// run for an arbitrarily long time without triggering the libc interceptors. -// See https://golang.org/issue/18717. - -import ( - "os" - "os/signal" - "syscall" -) - -/* -#cgo CFLAGS: -g -fsanitize=thread -#cgo LDFLAGS: -g -fsanitize=thread -*/ -import "C" - -func main() { - c := make(chan os.Signal, 1) - signal.Notify(c, syscall.SIGUSR1) - defer signal.Stop(c) - syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) - <-c -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan11.go b/libgo/misc/cgo/testsanitizers/src/tsan11.go deleted file mode 100644 index 70ac9c8..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan11.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program hung when run under the C/C++ ThreadSanitizer. TSAN defers -// asynchronous signals until the signaled thread calls into libc. The runtime's -// sysmon goroutine idles itself using direct usleep syscalls, so it could -// run for an arbitrarily long time without triggering the libc interceptors. -// See https://golang.org/issue/18717. - -import ( - "os" - "os/signal" - "syscall" -) - -/* -#cgo CFLAGS: -g -fsanitize=thread -#cgo LDFLAGS: -g -fsanitize=thread - -#include -#include -#include -#include - -static void raise_usr2(int signo) { - raise(SIGUSR2); -} - -static void register_handler(int signo) { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_ONSTACK; - sa.sa_handler = raise_usr2; - - if (sigaction(SIGUSR1, &sa, NULL) != 0) { - perror("failed to register SIGUSR1 handler"); - exit(EXIT_FAILURE); - } -} -*/ -import "C" - -func main() { - ch := make(chan os.Signal) - signal.Notify(ch, syscall.SIGUSR2) - - C.register_handler(C.int(syscall.SIGUSR1)) - syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) - - <-ch -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan12.go b/libgo/misc/cgo/testsanitizers/src/tsan12.go deleted file mode 100644 index 3e767ee..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan12.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program hung when run under the C/C++ ThreadSanitizer. TSAN installs a -// libc interceptor that writes signal handlers to a global variable within the -// TSAN runtime instead of making a sigaction system call. A bug in -// syscall.runtime_AfterForkInChild corrupted TSAN's signal forwarding table -// during calls to (*os/exec.Cmd).Run, causing the parent process to fail to -// invoke signal handlers. - -import ( - "fmt" - "os" - "os/exec" - "os/signal" - "syscall" -) - -import "C" - -func main() { - ch := make(chan os.Signal) - signal.Notify(ch, syscall.SIGUSR1) - - if err := exec.Command("true").Run(); err != nil { - fmt.Fprintf(os.Stderr, "Unexpected error from `true`: %v", err) - os.Exit(1) - } - - syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) - <-ch -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan2.go b/libgo/misc/cgo/testsanitizers/src/tsan2.go deleted file mode 100644 index 5018a19..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan2.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program produced false race reports when run under the C/C++ -// ThreadSanitizer, as it did not understand the synchronization in -// the Go code. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -extern void GoRun(void); - -// Yes, you can have definitions if you use //export, as long as they are weak. - -int val __attribute__ ((weak)); - -int run(void) __attribute__ ((weak)); - -int run() { - val = 1; - GoRun(); - return val; -} - -void setVal(int) __attribute__ ((weak)); - -void setVal(int i) { - val = i; -} -*/ -import "C" - -import "runtime" - -//export GoRun -func GoRun() { - runtime.LockOSThread() - c := make(chan bool) - go func() { - runtime.LockOSThread() - C.setVal(2) - c <- true - }() - <-c -} - -func main() { - if v := C.run(); v != 2 { - panic(v) - } -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan3.go b/libgo/misc/cgo/testsanitizers/src/tsan3.go deleted file mode 100644 index 87f6c80..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan3.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// The stubs for the C functions read and write the same slot on the -// g0 stack when copying arguments in and out. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -int Func1() { - return 0; -} - -void Func2(int x) { - (void)x; -} -*/ -import "C" - -func main() { - const N = 10000 - done := make(chan bool, N) - for i := 0; i < N; i++ { - go func() { - C.Func1() - done <- true - }() - go func() { - C.Func2(0) - done <- true - }() - } - for i := 0; i < 2*N; i++ { - <-done - } -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan4.go b/libgo/misc/cgo/testsanitizers/src/tsan4.go deleted file mode 100644 index f0c76d8..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan4.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Check that calls to C.malloc/C.free do not trigger TSAN false -// positive reports. - -// #cgo CFLAGS: -fsanitize=thread -// #cgo LDFLAGS: -fsanitize=thread -// #include -import "C" - -import ( - "runtime" - "sync" -) - -func main() { - var wg sync.WaitGroup - for i := 0; i < 10; i++ { - wg.Add(1) - go func() { - defer wg.Done() - for i := 0; i < 100; i++ { - p := C.malloc(C.size_t(i * 10)) - runtime.Gosched() - C.free(p) - } - }() - } - wg.Wait() -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan5.go b/libgo/misc/cgo/testsanitizers/src/tsan5.go deleted file mode 100644 index 1214a77..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan5.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Check that calls to C.malloc/C.free do not collide with the calls -// made by the os/user package. - -// #cgo CFLAGS: -fsanitize=thread -// #cgo LDFLAGS: -fsanitize=thread -// #include -import "C" - -import ( - "fmt" - "os" - "os/user" - "runtime" - "sync" -) - -func main() { - u, err := user.Current() - if err != nil { - fmt.Fprintln(os.Stderr, err) - // Let the test pass. - os.Exit(0) - } - - var wg sync.WaitGroup - for i := 0; i < 20; i++ { - wg.Add(2) - go func() { - defer wg.Done() - for i := 0; i < 1000; i++ { - user.Lookup(u.Username) - runtime.Gosched() - } - }() - go func() { - defer wg.Done() - for i := 0; i < 1000; i++ { - p := C.malloc(C.size_t(len(u.Username) + 1)) - runtime.Gosched() - C.free(p) - } - }() - } - wg.Wait() -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan6.go b/libgo/misc/cgo/testsanitizers/src/tsan6.go deleted file mode 100644 index c96f08d..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan6.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Check that writes to Go allocated memory, with Go synchronization, -// do not look like a race. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -void f(char *p) { - *p = 1; -} -*/ -import "C" - -import ( - "runtime" - "sync" -) - -func main() { - var wg sync.WaitGroup - var mu sync.Mutex - c := make(chan []C.char, 100) - for i := 0; i < 10; i++ { - wg.Add(2) - go func() { - defer wg.Done() - for i := 0; i < 100; i++ { - c <- make([]C.char, 4096) - runtime.Gosched() - } - }() - go func() { - defer wg.Done() - for i := 0; i < 100; i++ { - p := &(<-c)[0] - mu.Lock() - C.f(p) - mu.Unlock() - } - }() - } - wg.Wait() -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan7.go b/libgo/misc/cgo/testsanitizers/src/tsan7.go deleted file mode 100644 index 2fb9e45..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan7.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// Setting an environment variable in a cgo program changes the C -// environment. Test that this does not confuse the race detector. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread -*/ -import "C" - -import ( - "fmt" - "os" - "sync" - "time" -) - -func main() { - var wg sync.WaitGroup - var mu sync.Mutex - f := func() { - defer wg.Done() - for i := 0; i < 100; i++ { - time.Sleep(time.Microsecond) - mu.Lock() - s := fmt.Sprint(i) - os.Setenv("TSAN_TEST"+s, s) - mu.Unlock() - } - } - wg.Add(2) - go f() - go f() - wg.Wait() -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan8.go b/libgo/misc/cgo/testsanitizers/src/tsan8.go deleted file mode 100644 index 88d82a6..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan8.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program failed when run under the C/C++ ThreadSanitizer. The TSAN -// sigaction function interceptor returned SIG_DFL instead of the Go runtime's -// handler in registerSegvForwarder. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -#include -#include -#include -#include - -struct sigaction prev_sa; - -void forwardSignal(int signo, siginfo_t *info, void *context) { - // One of sa_sigaction and/or sa_handler - if ((prev_sa.sa_flags&SA_SIGINFO) != 0) { - prev_sa.sa_sigaction(signo, info, context); - return; - } - if (prev_sa.sa_handler != SIG_IGN && prev_sa.sa_handler != SIG_DFL) { - prev_sa.sa_handler(signo); - return; - } - - fprintf(stderr, "No Go handler to forward to!\n"); - abort(); -} - -void registerSegvFowarder() { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO | SA_ONSTACK; - sa.sa_sigaction = forwardSignal; - - if (sigaction(SIGSEGV, &sa, &prev_sa) != 0) { - perror("failed to register SEGV forwarder"); - exit(EXIT_FAILURE); - } -} -*/ -import "C" - -func main() { - C.registerSegvFowarder() - - defer func() { - recover() - }() - var nilp *int - *nilp = 42 -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan9.go b/libgo/misc/cgo/testsanitizers/src/tsan9.go deleted file mode 100644 index f166d8b..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan9.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program failed when run under the C/C++ ThreadSanitizer. The -// TSAN library was not keeping track of whether signals should be -// delivered on the alternate signal stack, and the Go signal handler -// was not preserving callee-saved registers from C callers. - -/* -#cgo CFLAGS: -g -fsanitize=thread -#cgo LDFLAGS: -g -fsanitize=thread - -#include -#include - -void spin() { - size_t n; - struct timeval tvstart, tvnow; - int diff; - void *prev = NULL, *cur; - - gettimeofday(&tvstart, NULL); - for (n = 0; n < 1<<20; n++) { - cur = malloc(n); - free(prev); - prev = cur; - - gettimeofday(&tvnow, NULL); - diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec); - - // Profile frequency is 100Hz so we should definitely - // get a signal in 50 milliseconds. - if (diff > 50 * 1000) { - break; - } - } - - free(prev); -} -*/ -import "C" - -import ( - "io/ioutil" - "runtime/pprof" - "time" -) - -func goSpin() { - start := time.Now() - for n := 0; n < 1<<20; n++ { - _ = make([]byte, n) - if time.Since(start) > 50*time.Millisecond { - break - } - } -} - -func main() { - pprof.StartCPUProfile(ioutil.Discard) - go C.spin() - goSpin() - pprof.StopCPUProfile() -} diff --git a/libgo/misc/cgo/testsanitizers/src/tsan_shared.go b/libgo/misc/cgo/testsanitizers/src/tsan_shared.go deleted file mode 100644 index 55ff67e..0000000 --- a/libgo/misc/cgo/testsanitizers/src/tsan_shared.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -// This program failed with SIGSEGV when run under the C/C++ ThreadSanitizer. -// The Go runtime had re-registered the C handler with the wrong flags due to a -// typo, resulting in null pointers being passed for the info and context -// parameters to the handler. - -/* -#cgo CFLAGS: -fsanitize=thread -#cgo LDFLAGS: -fsanitize=thread - -#include -#include -#include -#include -#include - -void check_params(int signo, siginfo_t *info, void *context) { - ucontext_t* uc = (ucontext_t*)(context); - - if (info->si_signo != signo) { - fprintf(stderr, "info->si_signo does not match signo.\n"); - abort(); - } - - if (uc->uc_stack.ss_size == 0) { - fprintf(stderr, "uc_stack has size 0.\n"); - abort(); - } -} - - -// Set up the signal handler in a high priority constructor, so -// that it is installed before the Go code starts. - -static void register_handler(void) __attribute__ ((constructor (200))); - -static void register_handler() { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = check_params; - - if (sigaction(SIGUSR1, &sa, NULL) != 0) { - perror("failed to register SIGUSR1 handler"); - exit(EXIT_FAILURE); - } -} -*/ -import "C" - -import "syscall" - -func init() { - C.raise(C.int(syscall.SIGUSR1)) -} - -func main() {} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan.go b/libgo/misc/cgo/testsanitizers/testdata/msan.go new file mode 100644 index 0000000..7915fa8 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan.go @@ -0,0 +1,35 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include + +void f(int32_t *p, int n) { + int i; + + for (i = 0; i < n; i++) { + p[i] = (int32_t)i; + } +} +*/ +import "C" + +import ( + "fmt" + "os" + "unsafe" +) + +func main() { + a := make([]int32, 10) + C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) + for i, v := range a { + if i != int(v) { + fmt.Println("bad %d: %v\n", i, a) + os.Exit(1) + } + } +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan2.go b/libgo/misc/cgo/testsanitizers/testdata/msan2.go new file mode 100644 index 0000000..6690cb0 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan2.go @@ -0,0 +1,35 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include +#include +#include + +void f(int32_t *p, int n) { + int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); + memcpy(p, q, n * sizeof(*p)); + free(q); +} + +void g(int32_t *p, int n) { + if (p[4] != 1) { + abort(); + } +} +*/ +import "C" + +import ( + "unsafe" +) + +func main() { + a := make([]int32, 10) + C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) + a[4] = 1 + C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan2_cmsan.go b/libgo/misc/cgo/testsanitizers/testdata/msan2_cmsan.go new file mode 100644 index 0000000..8fdaea9 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan2_cmsan.go @@ -0,0 +1,38 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#cgo LDFLAGS: -fsanitize=memory +#cgo CPPFLAGS: -fsanitize=memory + +#include +#include +#include + +void f(int32_t *p, int n) { + int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); + memcpy(p, q, n * sizeof(*p)); + free(q); +} + +void g(int32_t *p, int n) { + if (p[4] != 1) { + abort(); + } +} +*/ +import "C" + +import ( + "unsafe" +) + +func main() { + a := make([]int32, 10) + C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) + a[4] = 1 + C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan3.go b/libgo/misc/cgo/testsanitizers/testdata/msan3.go new file mode 100644 index 0000000..61a9c29 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan3.go @@ -0,0 +1,33 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +extern int *GoFn(int *); + +// Yes, you can have definitions if you use //export, as long as they are weak. +int f(void) __attribute__ ((weak)); + +int f() { + int i; + int *p = GoFn(&i); + if (*p != 12345) + return 0; + return 1; +} +*/ +import "C" + +//export GoFn +func GoFn(p *C.int) *C.int { + *p = C.int(12345) + return p +} + +func main() { + if r := C.f(); r != 1 { + panic(r) + } +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan4.go b/libgo/misc/cgo/testsanitizers/testdata/msan4.go new file mode 100644 index 0000000..6c91ff5 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan4.go @@ -0,0 +1,50 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// The memory profiler can call copy from a slice on the system stack, +// which msan used to think meant a reference to uninitialized memory. + +/* +#include +#include + +extern void Nop(char*); + +// Use weak as a hack to permit defining a function even though we use export. +void poison() __attribute__ ((weak)); + +// Poison the stack. +void poison() { + char a[1024]; + Nop(&a[0]); +} + +*/ +import "C" + +import ( + "runtime" +) + +func main() { + runtime.MemProfileRate = 1 + start(100) +} + +func start(i int) { + if i == 0 { + return + } + C.poison() + // Tie up a thread. + // We won't actually wait for this sleep to complete. + go func() { C.sleep(1) }() + start(i - 1) +} + +//export Nop +func Nop(*C.char) { +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan5.go b/libgo/misc/cgo/testsanitizers/testdata/msan5.go new file mode 100644 index 0000000..f1479eb --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan5.go @@ -0,0 +1,57 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Using reflect to set a value was not seen by msan. + +/* +#include + +extern void Go1(int*); +extern void Go2(char*); + +// Use weak as a hack to permit defining a function even though we use export. +void C1() __attribute__ ((weak)); +void C2() __attribute__ ((weak)); + +void C1() { + int i; + Go1(&i); + if (i != 42) { + abort(); + } +} + +void C2() { + char a[2]; + a[1] = 42; + Go2(a); + if (a[0] != 42) { + abort(); + } +} +*/ +import "C" + +import ( + "reflect" + "unsafe" +) + +//export Go1 +func Go1(p *C.int) { + reflect.ValueOf(p).Elem().Set(reflect.ValueOf(C.int(42))) +} + +//export Go2 +func Go2(p *C.char) { + a := (*[2]byte)(unsafe.Pointer(p)) + reflect.Copy(reflect.ValueOf(a[:1]), reflect.ValueOf(a[1:])) +} + +func main() { + C.C1() + C.C2() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan6.go b/libgo/misc/cgo/testsanitizers/testdata/msan6.go new file mode 100644 index 0000000..003989c --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan6.go @@ -0,0 +1,72 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// A C function returning a value on the Go stack could leave the Go +// stack marked as uninitialized, potentially causing a later error +// when the stack is used for something else. Issue 26209. + +/* +#cgo LDFLAGS: -fsanitize=memory +#cgo CPPFLAGS: -fsanitize=memory + +#include +#include +#include + +typedef struct { + uintptr_t a[20]; +} S; + +S f() { + S *p; + + p = (S *)(malloc(sizeof(S))); + p->a[0] = 0; + return *p; +} +*/ +import "C" + +// allocateStack extends the stack so that stack copying doesn't +// confuse the msan data structures. +//go:noinline +func allocateStack(i int) int { + if i == 0 { + return i + } + return allocateStack(i - 1) +} + +// F1 marks a chunk of stack as uninitialized. +// C.f returns an uninitialized struct on the stack, so msan will mark +// the stack as uninitialized. +//go:noinline +func F1() uintptr { + s := C.f() + return uintptr(s.a[0]) +} + +// F2 allocates a struct on the stack and converts it to an empty interface, +// which will call msanread and see that the data appears uninitialized. +//go:noinline +func F2() interface{} { + return C.S{} +} + +func poisonStack(i int) int { + if i == 0 { + return int(F1()) + } + F1() + r := poisonStack(i - 1) + F2() + return r +} + +func main() { + allocateStack(16384) + poisonStack(128) +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan_fail.go b/libgo/misc/cgo/testsanitizers/testdata/msan_fail.go new file mode 100644 index 0000000..4c8dab3 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan_fail.go @@ -0,0 +1,36 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +/* +#include +#include +#include + +void f(int32_t *p, int n) { + int32_t * volatile q = (int32_t *)malloc(sizeof(int32_t) * n); + memcpy(p, q, n * sizeof(*p)); + free(q); +} + +void g(int32_t *p, int n) { + if (p[4] != 1) { + // We shouldn't get here; msan should stop us first. + exit(0); + } +} +*/ +import "C" + +import ( + "unsafe" +) + +func main() { + a := make([]int32, 10) + C.f((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) + a[3] = 1 + C.g((*C.int32_t)(unsafe.Pointer(&a[0])), C.int(len(a))) +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/msan_shared.go b/libgo/misc/cgo/testsanitizers/testdata/msan_shared.go new file mode 100644 index 0000000..966947c --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/msan_shared.go @@ -0,0 +1,12 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This program segfaulted during libpreinit when built with -msan: +// http://golang.org/issue/18707 + +package main + +import "C" + +func main() {} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan.go b/libgo/misc/cgo/testsanitizers/testdata/tsan.go new file mode 100644 index 0000000..6c377a7 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan.go @@ -0,0 +1,44 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program produced false race reports when run under the C/C++ +// ThreadSanitizer, as it did not understand the synchronization in +// the Go code. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +int val; + +int getVal() { + return val; +} + +void setVal(int i) { + val = i; +} +*/ +import "C" + +import ( + "runtime" +) + +func main() { + runtime.LockOSThread() + C.setVal(1) + c := make(chan bool) + go func() { + runtime.LockOSThread() + C.setVal(2) + c <- true + }() + <-c + if v := C.getVal(); v != 2 { + panic(v) + } +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan10.go b/libgo/misc/cgo/testsanitizers/testdata/tsan10.go new file mode 100644 index 0000000..a40f245 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan10.go @@ -0,0 +1,31 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program hung when run under the C/C++ ThreadSanitizer. +// TSAN defers asynchronous signals until the signaled thread calls into libc. +// Since the Go runtime makes direct futex syscalls, Go runtime threads could +// run for an arbitrarily long time without triggering the libc interceptors. +// See https://golang.org/issue/18717. + +import ( + "os" + "os/signal" + "syscall" +) + +/* +#cgo CFLAGS: -g -fsanitize=thread +#cgo LDFLAGS: -g -fsanitize=thread +*/ +import "C" + +func main() { + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGUSR1) + defer signal.Stop(c) + syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) + <-c +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan11.go b/libgo/misc/cgo/testsanitizers/testdata/tsan11.go new file mode 100644 index 0000000..70ac9c8 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan11.go @@ -0,0 +1,55 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program hung when run under the C/C++ ThreadSanitizer. TSAN defers +// asynchronous signals until the signaled thread calls into libc. The runtime's +// sysmon goroutine idles itself using direct usleep syscalls, so it could +// run for an arbitrarily long time without triggering the libc interceptors. +// See https://golang.org/issue/18717. + +import ( + "os" + "os/signal" + "syscall" +) + +/* +#cgo CFLAGS: -g -fsanitize=thread +#cgo LDFLAGS: -g -fsanitize=thread + +#include +#include +#include +#include + +static void raise_usr2(int signo) { + raise(SIGUSR2); +} + +static void register_handler(int signo) { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_ONSTACK; + sa.sa_handler = raise_usr2; + + if (sigaction(SIGUSR1, &sa, NULL) != 0) { + perror("failed to register SIGUSR1 handler"); + exit(EXIT_FAILURE); + } +} +*/ +import "C" + +func main() { + ch := make(chan os.Signal) + signal.Notify(ch, syscall.SIGUSR2) + + C.register_handler(C.int(syscall.SIGUSR1)) + syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) + + <-ch +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan12.go b/libgo/misc/cgo/testsanitizers/testdata/tsan12.go new file mode 100644 index 0000000..3e767ee --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan12.go @@ -0,0 +1,35 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program hung when run under the C/C++ ThreadSanitizer. TSAN installs a +// libc interceptor that writes signal handlers to a global variable within the +// TSAN runtime instead of making a sigaction system call. A bug in +// syscall.runtime_AfterForkInChild corrupted TSAN's signal forwarding table +// during calls to (*os/exec.Cmd).Run, causing the parent process to fail to +// invoke signal handlers. + +import ( + "fmt" + "os" + "os/exec" + "os/signal" + "syscall" +) + +import "C" + +func main() { + ch := make(chan os.Signal) + signal.Notify(ch, syscall.SIGUSR1) + + if err := exec.Command("true").Run(); err != nil { + fmt.Fprintf(os.Stderr, "Unexpected error from `true`: %v", err) + os.Exit(1) + } + + syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) + <-ch +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan2.go b/libgo/misc/cgo/testsanitizers/testdata/tsan2.go new file mode 100644 index 0000000..5018a19 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan2.go @@ -0,0 +1,55 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program produced false race reports when run under the C/C++ +// ThreadSanitizer, as it did not understand the synchronization in +// the Go code. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +extern void GoRun(void); + +// Yes, you can have definitions if you use //export, as long as they are weak. + +int val __attribute__ ((weak)); + +int run(void) __attribute__ ((weak)); + +int run() { + val = 1; + GoRun(); + return val; +} + +void setVal(int) __attribute__ ((weak)); + +void setVal(int i) { + val = i; +} +*/ +import "C" + +import "runtime" + +//export GoRun +func GoRun() { + runtime.LockOSThread() + c := make(chan bool) + go func() { + runtime.LockOSThread() + C.setVal(2) + c <- true + }() + <-c +} + +func main() { + if v := C.run(); v != 2 { + panic(v) + } +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan3.go b/libgo/misc/cgo/testsanitizers/testdata/tsan3.go new file mode 100644 index 0000000..87f6c80 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan3.go @@ -0,0 +1,40 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// The stubs for the C functions read and write the same slot on the +// g0 stack when copying arguments in and out. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +int Func1() { + return 0; +} + +void Func2(int x) { + (void)x; +} +*/ +import "C" + +func main() { + const N = 10000 + done := make(chan bool, N) + for i := 0; i < N; i++ { + go func() { + C.Func1() + done <- true + }() + go func() { + C.Func2(0) + done <- true + }() + } + for i := 0; i < 2*N; i++ { + <-done + } +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan4.go b/libgo/misc/cgo/testsanitizers/testdata/tsan4.go new file mode 100644 index 0000000..f0c76d8 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan4.go @@ -0,0 +1,34 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Check that calls to C.malloc/C.free do not trigger TSAN false +// positive reports. + +// #cgo CFLAGS: -fsanitize=thread +// #cgo LDFLAGS: -fsanitize=thread +// #include +import "C" + +import ( + "runtime" + "sync" +) + +func main() { + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + p := C.malloc(C.size_t(i * 10)) + runtime.Gosched() + C.free(p) + } + }() + } + wg.Wait() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan5.go b/libgo/misc/cgo/testsanitizers/testdata/tsan5.go new file mode 100644 index 0000000..1214a77 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan5.go @@ -0,0 +1,51 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Check that calls to C.malloc/C.free do not collide with the calls +// made by the os/user package. + +// #cgo CFLAGS: -fsanitize=thread +// #cgo LDFLAGS: -fsanitize=thread +// #include +import "C" + +import ( + "fmt" + "os" + "os/user" + "runtime" + "sync" +) + +func main() { + u, err := user.Current() + if err != nil { + fmt.Fprintln(os.Stderr, err) + // Let the test pass. + os.Exit(0) + } + + var wg sync.WaitGroup + for i := 0; i < 20; i++ { + wg.Add(2) + go func() { + defer wg.Done() + for i := 0; i < 1000; i++ { + user.Lookup(u.Username) + runtime.Gosched() + } + }() + go func() { + defer wg.Done() + for i := 0; i < 1000; i++ { + p := C.malloc(C.size_t(len(u.Username) + 1)) + runtime.Gosched() + C.free(p) + } + }() + } + wg.Wait() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan6.go b/libgo/misc/cgo/testsanitizers/testdata/tsan6.go new file mode 100644 index 0000000..c96f08d --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan6.go @@ -0,0 +1,49 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Check that writes to Go allocated memory, with Go synchronization, +// do not look like a race. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +void f(char *p) { + *p = 1; +} +*/ +import "C" + +import ( + "runtime" + "sync" +) + +func main() { + var wg sync.WaitGroup + var mu sync.Mutex + c := make(chan []C.char, 100) + for i := 0; i < 10; i++ { + wg.Add(2) + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + c <- make([]C.char, 4096) + runtime.Gosched() + } + }() + go func() { + defer wg.Done() + for i := 0; i < 100; i++ { + p := &(<-c)[0] + mu.Lock() + C.f(p) + mu.Unlock() + } + }() + } + wg.Wait() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan7.go b/libgo/misc/cgo/testsanitizers/testdata/tsan7.go new file mode 100644 index 0000000..2fb9e45 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan7.go @@ -0,0 +1,40 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// Setting an environment variable in a cgo program changes the C +// environment. Test that this does not confuse the race detector. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread +*/ +import "C" + +import ( + "fmt" + "os" + "sync" + "time" +) + +func main() { + var wg sync.WaitGroup + var mu sync.Mutex + f := func() { + defer wg.Done() + for i := 0; i < 100; i++ { + time.Sleep(time.Microsecond) + mu.Lock() + s := fmt.Sprint(i) + os.Setenv("TSAN_TEST"+s, s) + mu.Unlock() + } + } + wg.Add(2) + go f() + go f() + wg.Wait() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan8.go b/libgo/misc/cgo/testsanitizers/testdata/tsan8.go new file mode 100644 index 0000000..88d82a6 --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan8.go @@ -0,0 +1,60 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program failed when run under the C/C++ ThreadSanitizer. The TSAN +// sigaction function interceptor returned SIG_DFL instead of the Go runtime's +// handler in registerSegvForwarder. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +#include +#include +#include +#include + +struct sigaction prev_sa; + +void forwardSignal(int signo, siginfo_t *info, void *context) { + // One of sa_sigaction and/or sa_handler + if ((prev_sa.sa_flags&SA_SIGINFO) != 0) { + prev_sa.sa_sigaction(signo, info, context); + return; + } + if (prev_sa.sa_handler != SIG_IGN && prev_sa.sa_handler != SIG_DFL) { + prev_sa.sa_handler(signo); + return; + } + + fprintf(stderr, "No Go handler to forward to!\n"); + abort(); +} + +void registerSegvFowarder() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + sa.sa_sigaction = forwardSignal; + + if (sigaction(SIGSEGV, &sa, &prev_sa) != 0) { + perror("failed to register SEGV forwarder"); + exit(EXIT_FAILURE); + } +} +*/ +import "C" + +func main() { + C.registerSegvFowarder() + + defer func() { + recover() + }() + var nilp *int + *nilp = 42 +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan9.go b/libgo/misc/cgo/testsanitizers/testdata/tsan9.go new file mode 100644 index 0000000..f166d8b --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan9.go @@ -0,0 +1,67 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program failed when run under the C/C++ ThreadSanitizer. The +// TSAN library was not keeping track of whether signals should be +// delivered on the alternate signal stack, and the Go signal handler +// was not preserving callee-saved registers from C callers. + +/* +#cgo CFLAGS: -g -fsanitize=thread +#cgo LDFLAGS: -g -fsanitize=thread + +#include +#include + +void spin() { + size_t n; + struct timeval tvstart, tvnow; + int diff; + void *prev = NULL, *cur; + + gettimeofday(&tvstart, NULL); + for (n = 0; n < 1<<20; n++) { + cur = malloc(n); + free(prev); + prev = cur; + + gettimeofday(&tvnow, NULL); + diff = (tvnow.tv_sec - tvstart.tv_sec) * 1000 * 1000 + (tvnow.tv_usec - tvstart.tv_usec); + + // Profile frequency is 100Hz so we should definitely + // get a signal in 50 milliseconds. + if (diff > 50 * 1000) { + break; + } + } + + free(prev); +} +*/ +import "C" + +import ( + "io/ioutil" + "runtime/pprof" + "time" +) + +func goSpin() { + start := time.Now() + for n := 0; n < 1<<20; n++ { + _ = make([]byte, n) + if time.Since(start) > 50*time.Millisecond { + break + } + } +} + +func main() { + pprof.StartCPUProfile(ioutil.Discard) + go C.spin() + goSpin() + pprof.StopCPUProfile() +} diff --git a/libgo/misc/cgo/testsanitizers/testdata/tsan_shared.go b/libgo/misc/cgo/testsanitizers/testdata/tsan_shared.go new file mode 100644 index 0000000..55ff67e --- /dev/null +++ b/libgo/misc/cgo/testsanitizers/testdata/tsan_shared.go @@ -0,0 +1,63 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// This program failed with SIGSEGV when run under the C/C++ ThreadSanitizer. +// The Go runtime had re-registered the C handler with the wrong flags due to a +// typo, resulting in null pointers being passed for the info and context +// parameters to the handler. + +/* +#cgo CFLAGS: -fsanitize=thread +#cgo LDFLAGS: -fsanitize=thread + +#include +#include +#include +#include +#include + +void check_params(int signo, siginfo_t *info, void *context) { + ucontext_t* uc = (ucontext_t*)(context); + + if (info->si_signo != signo) { + fprintf(stderr, "info->si_signo does not match signo.\n"); + abort(); + } + + if (uc->uc_stack.ss_size == 0) { + fprintf(stderr, "uc_stack has size 0.\n"); + abort(); + } +} + + +// Set up the signal handler in a high priority constructor, so +// that it is installed before the Go code starts. + +static void register_handler(void) __attribute__ ((constructor (200))); + +static void register_handler() { + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = check_params; + + if (sigaction(SIGUSR1, &sa, NULL) != 0) { + perror("failed to register SIGUSR1 handler"); + exit(EXIT_FAILURE); + } +} +*/ +import "C" + +import "syscall" + +func init() { + C.raise(C.int(syscall.SIGUSR1)) +} + +func main() {} diff --git a/libgo/misc/cgo/testsanitizers/tsan_test.go b/libgo/misc/cgo/testsanitizers/tsan_test.go index 1d769a9..ec4e003 100644 --- a/libgo/misc/cgo/testsanitizers/tsan_test.go +++ b/libgo/misc/cgo/testsanitizers/tsan_test.go @@ -5,15 +5,11 @@ package sanitizers_test import ( - "runtime" "strings" "testing" ) func TestTSAN(t *testing.T) { - if runtime.GOARCH == "arm64" { - t.Skip("skipping test; see https://golang.org/issue/25682") - } t.Parallel() requireOvercommit(t) config := configure("thread") diff --git a/libgo/misc/cgo/testshared/overlaydir_test.go b/libgo/misc/cgo/testshared/overlaydir_test.go new file mode 100644 index 0000000..68be056 --- /dev/null +++ b/libgo/misc/cgo/testshared/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package shared_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testshared/shared_test.go b/libgo/misc/cgo/testshared/shared_test.go index 41a24ef..ac1a1c7 100644 --- a/libgo/misc/cgo/testshared/shared_test.go +++ b/libgo/misc/cgo/testshared/shared_test.go @@ -44,31 +44,35 @@ func run(t *testing.T, msg string, args ...string) { // goCmd invokes the go tool with the installsuffix set up by TestMain. It calls // t.Fatalf if the command fails. -func goCmd(t *testing.T, args ...string) { +func goCmd(t *testing.T, args ...string) string { newargs := []string{args[0], "-installsuffix=" + suffix} if testing.Verbose() { newargs = append(newargs, "-x") } newargs = append(newargs, args[1:]...) c := exec.Command("go", newargs...) + + stderr := new(strings.Builder) var output []byte var err error if testing.Verbose() { - fmt.Printf("+ go %s\n", strings.Join(newargs, " ")) - c.Stdout = os.Stdout + fmt.Printf("+ go %s\n", strings.Join(args, " ")) c.Stderr = os.Stderr - err = c.Run() - output = []byte("(output above)") + stderr.WriteString("(output above)") } else { - output, err = c.CombinedOutput() + c.Stderr = stderr } + output, err = c.Output() + if err != nil { if t != nil { - t.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, output) + t.Helper() + t.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) } else { - log.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, output) + log.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) } } + return string(bytes.TrimSpace(output)) } // TestMain calls testMain so that the latter can use defer (TestMain exits with os.Exit). @@ -105,47 +109,33 @@ func testMain(m *testing.M) (int, error) { // Some tests need to edit the source in GOPATH, so copy this directory to a // temporary directory and chdir to that. - scratchDir, err := ioutil.TempDir("", "testshared") + gopath, err := ioutil.TempDir("", "testshared") if err != nil { return 0, fmt.Errorf("TempDir failed: %v", err) } if testing.Verbose() { - fmt.Printf("+ mkdir -p %s\n", scratchDir) - } - defer os.RemoveAll(scratchDir) - err = filepath.Walk(".", func(path string, info os.FileInfo, err error) error { - scratchPath := filepath.Join(scratchDir, path) - if info.IsDir() { - if path == "." { - return nil - } - if testing.Verbose() { - fmt.Printf("+ mkdir -p %s\n", scratchPath) - } - return os.Mkdir(scratchPath, info.Mode()) - } else { - fromBytes, err := ioutil.ReadFile(path) - if err != nil { - return err - } - if testing.Verbose() { - fmt.Printf("+ cp %s %s\n", path, scratchPath) - } - return ioutil.WriteFile(scratchPath, fromBytes, info.Mode()) - } - }) - if err != nil { - return 0, fmt.Errorf("walk failed: %v", err) + fmt.Printf("+ mkdir -p %s\n", gopath) + } + defer os.RemoveAll(gopath) + + modRoot := filepath.Join(gopath, "src", "testshared") + if err := overlayDir(modRoot, "testdata"); err != nil { + return 0, err } - os.Setenv("GOPATH", scratchDir) if testing.Verbose() { - fmt.Printf("+ export GOPATH=%s\n", scratchDir) + fmt.Printf("+ cd %s\n", modRoot) + } + os.Chdir(modRoot) + os.Setenv("PWD", modRoot) + if err := ioutil.WriteFile("go.mod", []byte("module testshared\n"), 0666); err != nil { + return 0, err } - myContext.GOPATH = scratchDir + + os.Setenv("GOPATH", gopath) if testing.Verbose() { - fmt.Printf("+ cd %s\n", scratchDir) + fmt.Printf("+ export GOPATH=%s\n", gopath) } - os.Chdir(scratchDir) + myContext.GOPATH = gopath // All tests depend on runtime being built into a shared library. Because // that takes a few seconds, do it here and have all tests use the version @@ -154,15 +144,20 @@ func testMain(m *testing.M) (int, error) { goCmd(nil, append([]string{"install", "-buildmode=shared"}, minpkgs...)...) myContext.InstallSuffix = suffix + "_dynlink" - depP, err := myContext.Import("depBase", ".", build.ImportComment) + depP, err := myContext.Import("./depBase", ".", build.ImportComment) if err != nil { return 0, fmt.Errorf("import failed: %v", err) } - gopathInstallDir = depP.PkgTargetRoot + if depP.PkgTargetRoot == "" { + gopathInstallDir = filepath.Dir(goCmd(nil, "list", "-buildmode=shared", "-f", "{{.Target}}", "./depBase")) + } else { + gopathInstallDir = filepath.Join(depP.PkgTargetRoot, "testshared") + } return m.Run(), nil } func TestMain(m *testing.M) { + log.SetFlags(log.Lshortfile) flag.Parse() // Some of the tests install binaries into a custom GOPATH. @@ -350,6 +345,7 @@ func readNotes(f *elf.File) ([]*note, error) { } func dynStrings(t *testing.T, path string, flag elf.DynTag) []string { + t.Helper() f, err := elf.Open(path) if err != nil { t.Fatalf("elf.Open(%q) failed: %v", path, err) @@ -363,6 +359,7 @@ func dynStrings(t *testing.T, path string, flag elf.DynTag) []string { } func AssertIsLinkedToRegexp(t *testing.T, path string, re *regexp.Regexp) { + t.Helper() for _, dynstring := range dynStrings(t, path, elf.DT_NEEDED) { if re.MatchString(dynstring) { return @@ -372,10 +369,12 @@ func AssertIsLinkedToRegexp(t *testing.T, path string, re *regexp.Regexp) { } func AssertIsLinkedTo(t *testing.T, path, lib string) { + t.Helper() AssertIsLinkedToRegexp(t, path, regexp.MustCompile(regexp.QuoteMeta(lib))) } func AssertHasRPath(t *testing.T, path, dir string) { + t.Helper() for _, tag := range []elf.DynTag{elf.DT_RPATH, elf.DT_RUNPATH} { for _, dynstring := range dynStrings(t, path, tag) { for _, rpath := range strings.Split(dynstring, ":") { @@ -390,15 +389,15 @@ func AssertHasRPath(t *testing.T, path, dir string) { // Build a trivial program that links against the shared runtime and check it runs. func TestTrivialExecutable(t *testing.T) { - goCmd(t, "install", "-linkshared", "trivial") - run(t, "trivial executable", "./bin/trivial") - AssertIsLinkedTo(t, "./bin/trivial", soname) - AssertHasRPath(t, "./bin/trivial", gorootInstallDir) + goCmd(t, "install", "-linkshared", "./trivial") + run(t, "trivial executable", "../../bin/trivial") + AssertIsLinkedTo(t, "../../bin/trivial", soname) + AssertHasRPath(t, "../../bin/trivial", gorootInstallDir) } // Build a trivial program in PIE mode that links against the shared runtime and check it runs. func TestTrivialExecutablePIE(t *testing.T) { - goCmd(t, "build", "-buildmode=pie", "-o", "trivial.pie", "-linkshared", "trivial") + goCmd(t, "build", "-buildmode=pie", "-o", "trivial.pie", "-linkshared", "./trivial") run(t, "trivial executable", "./trivial.pie") AssertIsLinkedTo(t, "./trivial.pie", soname) AssertHasRPath(t, "./trivial.pie", gorootInstallDir) @@ -406,15 +405,15 @@ func TestTrivialExecutablePIE(t *testing.T) { // Build a division test program and check it runs. func TestDivisionExecutable(t *testing.T) { - goCmd(t, "install", "-linkshared", "division") - run(t, "division executable", "./bin/division") + goCmd(t, "install", "-linkshared", "./division") + run(t, "division executable", "../../bin/division") } // Build an executable that uses cgo linked against the shared runtime and check it // runs. func TestCgoExecutable(t *testing.T) { - goCmd(t, "install", "-linkshared", "execgo") - run(t, "cgo executable", "./bin/execgo") + goCmd(t, "install", "-linkshared", "./execgo") + run(t, "cgo executable", "../../bin/execgo") } func checkPIE(t *testing.T, name string) { @@ -433,7 +432,7 @@ func checkPIE(t *testing.T, name string) { func TestTrivialPIE(t *testing.T) { name := "trivial_pie" - goCmd(t, "build", "-buildmode=pie", "-o="+name, "trivial") + goCmd(t, "build", "-buildmode=pie", "-o="+name, "./trivial") defer os.Remove(name) run(t, name, "./"+name) checkPIE(t, name) @@ -441,7 +440,7 @@ func TestTrivialPIE(t *testing.T) { func TestCgoPIE(t *testing.T) { name := "cgo_pie" - goCmd(t, "build", "-buildmode=pie", "-o="+name, "execgo") + goCmd(t, "build", "-buildmode=pie", "-o="+name, "./execgo") defer os.Remove(name) run(t, name, "./"+name) checkPIE(t, name) @@ -450,15 +449,16 @@ func TestCgoPIE(t *testing.T) { // Build a GOPATH package into a shared library that links against the goroot runtime // and an executable that links against both. func TestGopathShlib(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - AssertIsLinkedTo(t, filepath.Join(gopathInstallDir, "libdepBase.so"), soname) - goCmd(t, "install", "-linkshared", "exe") - AssertIsLinkedTo(t, "./bin/exe", soname) - AssertIsLinkedTo(t, "./bin/exe", "libdepBase.so") - AssertHasRPath(t, "./bin/exe", gorootInstallDir) - AssertHasRPath(t, "./bin/exe", gopathInstallDir) + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + shlib := goCmd(t, "list", "-f", "{{.Shlib}}", "-buildmode=shared", "-linkshared", "./depBase") + AssertIsLinkedTo(t, shlib, soname) + goCmd(t, "install", "-linkshared", "./exe") + AssertIsLinkedTo(t, "../../bin/exe", soname) + AssertIsLinkedTo(t, "../../bin/exe", filepath.Base(shlib)) + AssertHasRPath(t, "../../bin/exe", gorootInstallDir) + AssertHasRPath(t, "../../bin/exe", filepath.Dir(gopathInstallDir)) // And check it runs. - run(t, "executable linked to GOPATH library", "./bin/exe") + run(t, "executable linked to GOPATH library", "../../bin/exe") } // The shared library contains a note listing the packages it contains in a section @@ -470,8 +470,8 @@ func testPkgListNote(t *testing.T, f *elf.File, note *note) { if isOffsetLoaded(f, note.section.Offset) { t.Errorf("package list section contained in PT_LOAD segment") } - if note.desc != "depBase\n" { - t.Errorf("incorrect package list %q, want %q", note.desc, "depBase\n") + if note.desc != "testshared/depBase\n" { + t.Errorf("incorrect package list %q, want %q", note.desc, "testshared/depBase\n") } } @@ -528,8 +528,9 @@ func testDepsNote(t *testing.T, f *elf.File, note *note) { // The shared library contains notes with defined contents; see above. func TestNotes(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - f, err := elf.Open(filepath.Join(gopathInstallDir, "libdepBase.so")) + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + shlib := goCmd(t, "list", "-f", "{{.Shlib}}", "-buildmode=shared", "-linkshared", "./depBase") + f, err := elf.Open(shlib) if err != nil { t.Fatal(err) } @@ -581,23 +582,24 @@ func TestNotes(t *testing.T) { // runtime, another package (dep2) that links against the first, and an // executable that links against dep2. func TestTwoGopathShlibs(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep2") - goCmd(t, "install", "-linkshared", "exe2") - run(t, "executable linked to GOPATH library", "./bin/exe2") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./dep2") + goCmd(t, "install", "-linkshared", "./exe2") + run(t, "executable linked to GOPATH library", "../../bin/exe2") } func TestThreeGopathShlibs(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep2") - goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep3") - goCmd(t, "install", "-linkshared", "exe3") - run(t, "executable linked to GOPATH library", "./bin/exe3") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./dep2") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./dep3") + goCmd(t, "install", "-linkshared", "./exe3") + run(t, "executable linked to GOPATH library", "../../bin/exe3") } -// If gccgo is not available or not new enough call t.Skip. Otherwise, -// return a build.Context that is set up for gccgo. -func prepGccgo(t *testing.T) build.Context { +// If gccgo is not available or not new enough, call t.Skip. +func requireGccgo(t *testing.T) { + t.Helper() + gccgoName := os.Getenv("GCCGO") if gccgoName == "" { gccgoName = "gccgo" @@ -614,61 +616,64 @@ func prepGccgo(t *testing.T) build.Context { if string(output) < "5" { t.Skipf("gccgo too old (%s)", strings.TrimSpace(string(output))) } - gccgoContext := build.Default - gccgoContext.InstallSuffix = suffix + "_fPIC" - gccgoContext.Compiler = "gccgo" - gccgoContext.GOPATH = os.Getenv("GOPATH") - return gccgoContext + + gomod, err := exec.Command("go", "env", "GOMOD").Output() + if err != nil { + t.Fatalf("go env GOMOD: %v", err) + } + if len(bytes.TrimSpace(gomod)) > 0 { + t.Skipf("gccgo not supported in module mode; see golang.org/issue/30344") + } } // Build a GOPATH package into a shared library with gccgo and an executable that // links against it. func TestGoPathShlibGccgo(t *testing.T) { - gccgoContext := prepGccgo(t) + requireGccgo(t) libgoRE := regexp.MustCompile("libgo.so.[0-9]+") - depP, err := gccgoContext.Import("depBase", ".", build.ImportComment) - if err != nil { - t.Fatalf("import failed: %v", err) - } - gccgoInstallDir := filepath.Join(depP.PkgTargetRoot, "shlibs") - goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "depBase") - AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdepBase.so"), libgoRE) - goCmd(t, "install", "-compiler=gccgo", "-linkshared", "exe") - AssertIsLinkedToRegexp(t, "./bin/exe", libgoRE) - AssertIsLinkedTo(t, "./bin/exe", "libdepBase.so") - AssertHasRPath(t, "./bin/exe", gccgoInstallDir) + goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "./depBase") + + // Run 'go list' after 'go install': with gccgo, we apparently don't know the + // shlib location until after we've installed it. + shlib := goCmd(t, "list", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "-f", "{{.Shlib}}", "./depBase") + + AssertIsLinkedToRegexp(t, shlib, libgoRE) + goCmd(t, "install", "-compiler=gccgo", "-linkshared", "./exe") + AssertIsLinkedToRegexp(t, "../../bin/exe", libgoRE) + AssertIsLinkedTo(t, "../../bin/exe", filepath.Base(shlib)) + AssertHasRPath(t, "../../bin/exe", filepath.Dir(shlib)) // And check it runs. - run(t, "gccgo-built", "./bin/exe") + run(t, "gccgo-built", "../../bin/exe") } // The gccgo version of TestTwoGopathShlibs: build a GOPATH package into a shared // library with gccgo, another GOPATH package that depends on the first and an // executable that links the second library. func TestTwoGopathShlibsGccgo(t *testing.T) { - gccgoContext := prepGccgo(t) + requireGccgo(t) libgoRE := regexp.MustCompile("libgo.so.[0-9]+") - depP, err := gccgoContext.Import("depBase", ".", build.ImportComment) - if err != nil { - t.Fatalf("import failed: %v", err) - } - gccgoInstallDir := filepath.Join(depP.PkgTargetRoot, "shlibs") - goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "depBase") - goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "dep2") - goCmd(t, "install", "-compiler=gccgo", "-linkshared", "exe2") + goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "./depBase") + goCmd(t, "install", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "./dep2") + goCmd(t, "install", "-compiler=gccgo", "-linkshared", "./exe2") + + // Run 'go list' after 'go install': with gccgo, we apparently don't know the + // shlib location until after we've installed it. + dep2 := goCmd(t, "list", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "-f", "{{.Shlib}}", "./dep2") + depBase := goCmd(t, "list", "-compiler=gccgo", "-buildmode=shared", "-linkshared", "-f", "{{.Shlib}}", "./depBase") - AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdepBase.so"), libgoRE) - AssertIsLinkedToRegexp(t, filepath.Join(gccgoInstallDir, "libdep2.so"), libgoRE) - AssertIsLinkedTo(t, filepath.Join(gccgoInstallDir, "libdep2.so"), "libdepBase.so") - AssertIsLinkedToRegexp(t, "./bin/exe2", libgoRE) - AssertIsLinkedTo(t, "./bin/exe2", "libdep2") - AssertIsLinkedTo(t, "./bin/exe2", "libdepBase.so") + AssertIsLinkedToRegexp(t, depBase, libgoRE) + AssertIsLinkedToRegexp(t, dep2, libgoRE) + AssertIsLinkedTo(t, dep2, filepath.Base(depBase)) + AssertIsLinkedToRegexp(t, "../../bin/exe2", libgoRE) + AssertIsLinkedTo(t, "../../bin/exe2", filepath.Base(dep2)) + AssertIsLinkedTo(t, "../../bin/exe2", filepath.Base(depBase)) // And check it runs. - run(t, "gccgo-built", "./bin/exe2") + run(t, "gccgo-built", "../../bin/exe2") } // Testing rebuilding of shared libraries when they are stale is a bit more @@ -694,9 +699,9 @@ func resetFileStamps() { } } - reset("bin") - reset("pkg") - reset("src") + reset("../../bin") + reset("../../pkg") + reset("../../src") reset(gorootInstallDir) } @@ -746,6 +751,7 @@ func touch(t *testing.T, path string) (cleanup func()) { // isNew returns if the path is newer than the time stamp used by touch. func isNew(t *testing.T, path string) bool { + t.Helper() fi, err := os.Stat(path) if err != nil { t.Fatal(err) @@ -771,40 +777,47 @@ func AssertNotRebuilt(t *testing.T, msg, path string) { } func TestRebuilding(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - goCmd(t, "install", "-linkshared", "exe") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + goCmd(t, "install", "-linkshared", "./exe") + info := strings.Fields(goCmd(t, "list", "-buildmode=shared", "-linkshared", "-f", "{{.Target}} {{.Shlib}}", "./depBase")) + if len(info) != 2 { + t.Fatalf("go list failed to report Target and/or Shlib") + } + target := info[0] + shlib := info[1] // If the source is newer than both the .a file and the .so, both are rebuilt. t.Run("newsource", func(t *testing.T) { resetFileStamps() - cleanup := touch(t, "src/depBase/dep.go") + cleanup := touch(t, "./depBase/dep.go") defer func() { cleanup() - goCmd(t, "install", "-linkshared", "exe") + goCmd(t, "install", "-linkshared", "./exe") }() - goCmd(t, "install", "-linkshared", "exe") - AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "depBase.a")) - AssertRebuilt(t, "new source", filepath.Join(gopathInstallDir, "libdepBase.so")) + goCmd(t, "install", "-linkshared", "./exe") + AssertRebuilt(t, "new source", target) + AssertRebuilt(t, "new source", shlib) }) // If the .a file is newer than the .so, the .so is rebuilt (but not the .a) t.Run("newarchive", func(t *testing.T) { resetFileStamps() - AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a")) - goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase") - AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a")) - cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a")) + AssertNotRebuilt(t, "new .a file before build", target) + goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "./depBase") + AssertNotRebuilt(t, "new .a file before build", target) + cleanup := touch(t, target) defer func() { cleanup() - goCmd(t, "install", "-v", "-linkshared", "exe") + goCmd(t, "install", "-v", "-linkshared", "./exe") }() - goCmd(t, "install", "-v", "-linkshared", "exe") - AssertNotRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "depBase.a")) - AssertRebuilt(t, "new .a file", filepath.Join(gopathInstallDir, "libdepBase.so")) + goCmd(t, "install", "-v", "-linkshared", "./exe") + AssertNotRebuilt(t, "new .a file", target) + AssertRebuilt(t, "new .a file", shlib) }) } func appendFile(t *testing.T, path, content string) { + t.Helper() f, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0660) if err != nil { t.Fatalf("os.OpenFile failed: %v", err) @@ -821,16 +834,24 @@ func appendFile(t *testing.T, path, content string) { } } -func writeFile(t *testing.T, path, content string) { - err := ioutil.WriteFile(path, []byte(content), 0644) +func createFile(t *testing.T, path, content string) { + t.Helper() + f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644) if err != nil { - t.Fatalf("ioutil.WriteFile failed: %v", err) + t.Fatalf("os.OpenFile failed: %v", err) + } + _, err = f.WriteString(content) + if closeErr := f.Close(); err == nil { + err = closeErr + } + if err != nil { + t.Fatalf("WriteString failed: %v", err) } } func TestABIChecking(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - goCmd(t, "install", "-linkshared", "exe") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + goCmd(t, "install", "-linkshared", "./exe") // If we make an ABI-breaking change to depBase and rebuild libp.so but not exe, // exe will abort with a complaint on startup. @@ -838,18 +859,21 @@ func TestABIChecking(t *testing.T) { // some senses but suffices for the narrow definition of ABI compatibility the // toolchain uses today. resetFileStamps() - appendFile(t, "src/depBase/dep.go", "func ABIBreak() {}\n") - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - c := exec.Command("./bin/exe") + + createFile(t, "./depBase/break.go", "package depBase\nfunc ABIBreak() {}\n") + defer os.Remove("./depBase/break.go") + + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + c := exec.Command("../../bin/exe") output, err := c.CombinedOutput() if err == nil { t.Fatal("executing exe did not fail after ABI break") } scanner := bufio.NewScanner(bytes.NewReader(output)) foundMsg := false - const wantLine = "abi mismatch detected between the executable and libdepBase.so" + const wantPrefix = "abi mismatch detected between the executable and lib" for scanner.Scan() { - if scanner.Text() == wantLine { + if strings.HasPrefix(scanner.Text(), wantPrefix) { foundMsg = true break } @@ -858,20 +882,20 @@ func TestABIChecking(t *testing.T) { t.Errorf("scanner encountered error: %v", err) } if !foundMsg { - t.Fatalf("exe failed, but without line %q; got output:\n%s", wantLine, output) + t.Fatalf("exe failed, but without line %q; got output:\n%s", wantPrefix, output) } // Rebuilding exe makes it work again. - goCmd(t, "install", "-linkshared", "exe") - run(t, "rebuilt exe", "./bin/exe") + goCmd(t, "install", "-linkshared", "./exe") + run(t, "rebuilt exe", "../../bin/exe") // If we make a change which does not break ABI (such as adding an unexported // function) and rebuild libdepBase.so, exe still works, even if new function // is in a file by itself. resetFileStamps() - writeFile(t, "src/depBase/dep2.go", "package depBase\nfunc noABIBreak() {}\n") - goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase") - run(t, "after non-ABI breaking change", "./bin/exe") + createFile(t, "./depBase/dep2.go", "package depBase\nfunc noABIBreak() {}\n") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./depBase") + run(t, "after non-ABI breaking change", "../../bin/exe") } // If a package 'explicit' imports a package 'implicit', building @@ -881,29 +905,29 @@ func TestABIChecking(t *testing.T) { // executable rather than fetching it from the shared library. The // link still succeeds and the executable still runs though. func TestImplicitInclusion(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "explicit") - goCmd(t, "install", "-linkshared", "implicitcmd") - run(t, "running executable linked against library that contains same package as it", "./bin/implicitcmd") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./explicit") + goCmd(t, "install", "-linkshared", "./implicitcmd") + run(t, "running executable linked against library that contains same package as it", "../../bin/implicitcmd") } // Tests to make sure that the type fields of empty interfaces and itab // fields of nonempty interfaces are unique even across modules, // so that interface equality works correctly. func TestInterface(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_a") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./iface_a") // Note: iface_i gets installed implicitly as a dependency of iface_a. - goCmd(t, "install", "-buildmode=shared", "-linkshared", "iface_b") - goCmd(t, "install", "-linkshared", "iface") - run(t, "running type/itab uniqueness tester", "./bin/iface") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./iface_b") + goCmd(t, "install", "-linkshared", "./iface") + run(t, "running type/itab uniqueness tester", "../../bin/iface") } // Access a global variable from a library. func TestGlobal(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "globallib") - goCmd(t, "install", "-linkshared", "global") - run(t, "global executable", "./bin/global") - AssertIsLinkedTo(t, "./bin/global", soname) - AssertHasRPath(t, "./bin/global", gorootInstallDir) + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./globallib") + goCmd(t, "install", "-linkshared", "./global") + run(t, "global executable", "../../bin/global") + AssertIsLinkedTo(t, "../../bin/global", soname) + AssertHasRPath(t, "../../bin/global", gorootInstallDir) } // Run a test using -linkshared of an installed shared package. @@ -915,5 +939,5 @@ func TestTestInstalledShared(t *testing.T) { // Test generated pointer method with -linkshared. // Issue 25065. func TestGeneratedMethod(t *testing.T) { - goCmd(t, "install", "-buildmode=shared", "-linkshared", "issue25065") + goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue25065") } diff --git a/libgo/misc/cgo/testshared/src/dep2/dep2.go b/libgo/misc/cgo/testshared/src/dep2/dep2.go deleted file mode 100644 index c2c812a..0000000 --- a/libgo/misc/cgo/testshared/src/dep2/dep2.go +++ /dev/null @@ -1,15 +0,0 @@ -package dep2 - -import "depBase" - -var W int = 1 - -var hasProg depBase.HasProg - -type Dep2 struct { - depBase.Dep -} - -func G() int { - return depBase.F() + 1 -} diff --git a/libgo/misc/cgo/testshared/src/dep3/dep3.go b/libgo/misc/cgo/testshared/src/dep3/dep3.go deleted file mode 100644 index 7b7c9da..0000000 --- a/libgo/misc/cgo/testshared/src/dep3/dep3.go +++ /dev/null @@ -1,22 +0,0 @@ -package dep3 - -// The point of this test file is that it references a type from -// depBase that is also referenced in dep2, but dep2 is loaded by the -// linker before depBase (because it is earlier in the import list). -// There was a bug in the linker where it would not correctly read out -// the type data in this case and later crash. - -import ( - "dep2" - "depBase" -) - -type Dep3 struct { - dep depBase.Dep - dep2 dep2.Dep2 -} - -func D3() int { - var x Dep3 - return x.dep.X + x.dep2.X -} diff --git a/libgo/misc/cgo/testshared/src/depBase/asm.s b/libgo/misc/cgo/testshared/src/depBase/asm.s deleted file mode 100644 index a8acf77f0..0000000 --- a/libgo/misc/cgo/testshared/src/depBase/asm.s +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -#include "textflag.h" - -TEXT ·ImplementedInAsm(SB),NOSPLIT,$0-0 - RET diff --git a/libgo/misc/cgo/testshared/src/depBase/dep.go b/libgo/misc/cgo/testshared/src/depBase/dep.go deleted file mode 100644 index e7cc7c8..0000000 --- a/libgo/misc/cgo/testshared/src/depBase/dep.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package depBase - -import ( - "os" - "reflect" -) - -var SlicePtr interface{} = &[]int{} - -var V int = 1 - -var HasMask []string = []string{"hi"} - -type HasProg struct { - array [1024]*byte -} - -type Dep struct { - X int -} - -func (d *Dep) Method() int { - // This code below causes various go.itab.* symbols to be generated in - // the shared library. Similar code in ../exe/exe.go results in - // exercising https://golang.org/issues/17594 - reflect.TypeOf(os.Stdout).Elem() - return 10 -} - -func F() int { - defer func() {}() - return V -} diff --git a/libgo/misc/cgo/testshared/src/depBase/gccgo.go b/libgo/misc/cgo/testshared/src/depBase/gccgo.go deleted file mode 100644 index 2b02a1e..0000000 --- a/libgo/misc/cgo/testshared/src/depBase/gccgo.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gccgo - -package depBase - -func ImplementedInAsm() {} diff --git a/libgo/misc/cgo/testshared/src/depBase/stubs.go b/libgo/misc/cgo/testshared/src/depBase/stubs.go deleted file mode 100644 index 04534f3..0000000 --- a/libgo/misc/cgo/testshared/src/depBase/stubs.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !gccgo - -package depBase - -func ImplementedInAsm() diff --git a/libgo/misc/cgo/testshared/src/division/division.go b/libgo/misc/cgo/testshared/src/division/division.go deleted file mode 100644 index bb5fc98..0000000 --- a/libgo/misc/cgo/testshared/src/division/division.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -//go:noinline -func div(x, y uint32) uint32 { - return x / y -} - -func main() { - a := div(97, 11) - if a != 8 { - panic("FAIL") - } -} diff --git a/libgo/misc/cgo/testshared/src/exe/exe.go b/libgo/misc/cgo/testshared/src/exe/exe.go deleted file mode 100644 index bd864d8..0000000 --- a/libgo/misc/cgo/testshared/src/exe/exe.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "depBase" - "os" - "reflect" - "runtime" -) - -// Having a function declared in the main package triggered -// golang.org/issue/18250 -func DeclaredInMain() { -} - -type C struct { -} - -func F() *C { - return nil -} - -var slicePtr interface{} = &[]int{} - -func main() { - defer depBase.ImplementedInAsm() - // This code below causes various go.itab.* symbols to be generated in - // the executable. Similar code in ../depBase/dep.go results in - // exercising https://golang.org/issues/17594 - reflect.TypeOf(os.Stdout).Elem() - runtime.GC() - depBase.V = depBase.F() + 1 - - var c *C - if reflect.TypeOf(F).Out(0) != reflect.TypeOf(c) { - panic("bad reflection results, see golang.org/issue/18252") - } - - sp := reflect.New(reflect.TypeOf(slicePtr).Elem()) - s := sp.Interface() - - if reflect.TypeOf(s) != reflect.TypeOf(slicePtr) { - panic("bad reflection results, see golang.org/issue/18729") - } -} diff --git a/libgo/misc/cgo/testshared/src/exe2/exe2.go b/libgo/misc/cgo/testshared/src/exe2/exe2.go deleted file mode 100644 index 675fd1f..0000000 --- a/libgo/misc/cgo/testshared/src/exe2/exe2.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -import "dep2" - -func main() { - d := &dep2.Dep2{} - dep2.W = dep2.G() + 1 + d.Method() -} diff --git a/libgo/misc/cgo/testshared/src/exe3/exe3.go b/libgo/misc/cgo/testshared/src/exe3/exe3.go deleted file mode 100644 index 643f260..0000000 --- a/libgo/misc/cgo/testshared/src/exe3/exe3.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "dep3" - -func main() { - dep3.D3() -} diff --git a/libgo/misc/cgo/testshared/src/execgo/exe.go b/libgo/misc/cgo/testshared/src/execgo/exe.go deleted file mode 100644 index 0427be8..0000000 --- a/libgo/misc/cgo/testshared/src/execgo/exe.go +++ /dev/null @@ -1,8 +0,0 @@ -package main - -/* - */ -import "C" - -func main() { -} diff --git a/libgo/misc/cgo/testshared/src/explicit/explicit.go b/libgo/misc/cgo/testshared/src/explicit/explicit.go deleted file mode 100644 index 6a4453f..0000000 --- a/libgo/misc/cgo/testshared/src/explicit/explicit.go +++ /dev/null @@ -1,9 +0,0 @@ -package explicit - -import ( - "implicit" -) - -func E() int { - return implicit.I() -} diff --git a/libgo/misc/cgo/testshared/src/global/main.go b/libgo/misc/cgo/testshared/src/global/main.go deleted file mode 100644 index 94e7f24..0000000 --- a/libgo/misc/cgo/testshared/src/global/main.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "globallib" -) - -//go:noinline -func testLoop() { - for i, s := range globallib.Data { - if s != int64(i) { - panic("testLoop: mismatch") - } - } -} - -//go:noinline -func ptrData() *[1<<20 + 10]int64 { - return &globallib.Data -} - -//go:noinline -func testMediumOffset() { - for i, s := range globallib.Data[1<<16-2:] { - if s != int64(i)+1<<16-2 { - panic("testMediumOffset: index mismatch") - } - } - - x := globallib.Data[1<<16-1] - if x != 1<<16-1 { - panic("testMediumOffset: direct mismatch") - } - - y := &globallib.Data[1<<16-3] - if y != &ptrData()[1<<16-3] { - panic("testMediumOffset: address mismatch") - } -} - -//go:noinline -func testLargeOffset() { - for i, s := range globallib.Data[1<<20:] { - if s != int64(i)+1<<20 { - panic("testLargeOffset: index mismatch") - } - } - - x := globallib.Data[1<<20+1] - if x != 1<<20+1 { - panic("testLargeOffset: direct mismatch") - } - - y := &globallib.Data[1<<20+2] - if y != &ptrData()[1<<20+2] { - panic("testLargeOffset: address mismatch") - } -} - -func main() { - testLoop() - - // SSA rules commonly merge offsets into addresses. These - // tests access global data in different ways to try - // and exercise different SSA rules. - testMediumOffset() - testLargeOffset() -} diff --git a/libgo/misc/cgo/testshared/src/globallib/global.go b/libgo/misc/cgo/testshared/src/globallib/global.go deleted file mode 100644 index b4372a2..0000000 --- a/libgo/misc/cgo/testshared/src/globallib/global.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package globallib - -// Data is large enough to that offsets into it do not fit into -// 16-bit or 20-bit immediates. Ideally we'd also try and overrun -// 32-bit immediates, but that requires the test machine to have -// too much memory. -var Data [1<<20 + 10]int64 - -func init() { - for i := range Data { - Data[i] = int64(i) - } -} diff --git a/libgo/misc/cgo/testshared/src/iface/main.go b/libgo/misc/cgo/testshared/src/iface/main.go deleted file mode 100644 index 3d5b54e..0000000 --- a/libgo/misc/cgo/testshared/src/iface/main.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "iface_a" -import "iface_b" - -func main() { - if iface_a.F() != iface_b.F() { - panic("empty interfaces not equal") - } - if iface_a.G() != iface_b.G() { - panic("non-empty interfaces not equal") - } -} diff --git a/libgo/misc/cgo/testshared/src/iface_a/a.go b/libgo/misc/cgo/testshared/src/iface_a/a.go deleted file mode 100644 index e11047c..0000000 --- a/libgo/misc/cgo/testshared/src/iface_a/a.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package iface_a - -import "iface_i" - -//go:noinline -func F() interface{} { - return (*iface_i.T)(nil) -} - -//go:noinline -func G() iface_i.I { - return (*iface_i.T)(nil) -} diff --git a/libgo/misc/cgo/testshared/src/iface_b/b.go b/libgo/misc/cgo/testshared/src/iface_b/b.go deleted file mode 100644 index 47aee2e..0000000 --- a/libgo/misc/cgo/testshared/src/iface_b/b.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package iface_b - -import "iface_i" - -//go:noinline -func F() interface{} { - return (*iface_i.T)(nil) -} - -//go:noinline -func G() iface_i.I { - return (*iface_i.T)(nil) -} diff --git a/libgo/misc/cgo/testshared/src/iface_i/i.go b/libgo/misc/cgo/testshared/src/iface_i/i.go deleted file mode 100644 index 31c8038..0000000 --- a/libgo/misc/cgo/testshared/src/iface_i/i.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package iface_i - -type I interface { - M() -} - -type T struct { -} - -func (t *T) M() { -} - -// *T implements I diff --git a/libgo/misc/cgo/testshared/src/implicit/implicit.go b/libgo/misc/cgo/testshared/src/implicit/implicit.go deleted file mode 100644 index 5360188..0000000 --- a/libgo/misc/cgo/testshared/src/implicit/implicit.go +++ /dev/null @@ -1,5 +0,0 @@ -package implicit - -func I() int { - return 42 -} diff --git a/libgo/misc/cgo/testshared/src/implicitcmd/implicitcmd.go b/libgo/misc/cgo/testshared/src/implicitcmd/implicitcmd.go deleted file mode 100644 index f611293..0000000 --- a/libgo/misc/cgo/testshared/src/implicitcmd/implicitcmd.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -import ( - "explicit" - "implicit" -) - -func main() { - println(implicit.I() + explicit.E()) -} diff --git a/libgo/misc/cgo/testshared/src/issue25065/a.go b/libgo/misc/cgo/testshared/src/issue25065/a.go deleted file mode 100644 index 979350f..0000000 --- a/libgo/misc/cgo/testshared/src/issue25065/a.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package issue25065 has a type with a method that is -// 1) referenced in a method expression -// 2) not called -// 3) not converted to an interface -// 4) is a value method but the reference is to the pointer method -// These cases avoid the call to makefuncsym from typecheckfunc, but we -// still need to call makefuncsym somehow or the symbol will not be defined. -package issue25065 - -type T int - -func (t T) M() {} - -func F() func(*T) { - return (*T).M -} diff --git a/libgo/misc/cgo/testshared/src/trivial/trivial.go b/libgo/misc/cgo/testshared/src/trivial/trivial.go deleted file mode 100644 index 6ade47c..0000000 --- a/libgo/misc/cgo/testshared/src/trivial/trivial.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -func main() { - // This is enough to make sure that the executable references - // a type descriptor, which was the cause of - // https://golang.org/issue/25970. - c := make(chan int) - _ = c -} diff --git a/libgo/misc/cgo/testshared/testdata/dep2/dep2.go b/libgo/misc/cgo/testshared/testdata/dep2/dep2.go new file mode 100644 index 0000000..94f38cf --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/dep2/dep2.go @@ -0,0 +1,15 @@ +package dep2 + +import "testshared/depBase" + +var W int = 1 + +var hasProg depBase.HasProg + +type Dep2 struct { + depBase.Dep +} + +func G() int { + return depBase.F() + 1 +} diff --git a/libgo/misc/cgo/testshared/testdata/dep3/dep3.go b/libgo/misc/cgo/testshared/testdata/dep3/dep3.go new file mode 100644 index 0000000..6b02ad2 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/dep3/dep3.go @@ -0,0 +1,22 @@ +package dep3 + +// The point of this test file is that it references a type from +// depBase that is also referenced in dep2, but dep2 is loaded by the +// linker before depBase (because it is earlier in the import list). +// There was a bug in the linker where it would not correctly read out +// the type data in this case and later crash. + +import ( + "testshared/dep2" + "testshared/depBase" +) + +type Dep3 struct { + dep depBase.Dep + dep2 dep2.Dep2 +} + +func D3() int { + var x Dep3 + return x.dep.X + x.dep2.X +} diff --git a/libgo/misc/cgo/testshared/testdata/depBase/asm.s b/libgo/misc/cgo/testshared/testdata/depBase/asm.s new file mode 100644 index 0000000..a8acf77f0 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/depBase/asm.s @@ -0,0 +1,10 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +#include "textflag.h" + +TEXT ·ImplementedInAsm(SB),NOSPLIT,$0-0 + RET diff --git a/libgo/misc/cgo/testshared/testdata/depBase/dep.go b/libgo/misc/cgo/testshared/testdata/depBase/dep.go new file mode 100644 index 0000000..e7cc7c8 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/depBase/dep.go @@ -0,0 +1,37 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package depBase + +import ( + "os" + "reflect" +) + +var SlicePtr interface{} = &[]int{} + +var V int = 1 + +var HasMask []string = []string{"hi"} + +type HasProg struct { + array [1024]*byte +} + +type Dep struct { + X int +} + +func (d *Dep) Method() int { + // This code below causes various go.itab.* symbols to be generated in + // the shared library. Similar code in ../exe/exe.go results in + // exercising https://golang.org/issues/17594 + reflect.TypeOf(os.Stdout).Elem() + return 10 +} + +func F() int { + defer func() {}() + return V +} diff --git a/libgo/misc/cgo/testshared/testdata/depBase/gccgo.go b/libgo/misc/cgo/testshared/testdata/depBase/gccgo.go new file mode 100644 index 0000000..2b02a1e --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/depBase/gccgo.go @@ -0,0 +1,9 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build gccgo + +package depBase + +func ImplementedInAsm() {} diff --git a/libgo/misc/cgo/testshared/testdata/depBase/stubs.go b/libgo/misc/cgo/testshared/testdata/depBase/stubs.go new file mode 100644 index 0000000..04534f3 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/depBase/stubs.go @@ -0,0 +1,9 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo + +package depBase + +func ImplementedInAsm() diff --git a/libgo/misc/cgo/testshared/testdata/division/division.go b/libgo/misc/cgo/testshared/testdata/division/division.go new file mode 100644 index 0000000..bb5fc98 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/division/division.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +//go:noinline +func div(x, y uint32) uint32 { + return x / y +} + +func main() { + a := div(97, 11) + if a != 8 { + panic("FAIL") + } +} diff --git a/libgo/misc/cgo/testshared/testdata/exe/exe.go b/libgo/misc/cgo/testshared/testdata/exe/exe.go new file mode 100644 index 0000000..ee95f97 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/exe/exe.go @@ -0,0 +1,45 @@ +package main + +import ( + "os" + "reflect" + "runtime" + + "testshared/depBase" +) + +// Having a function declared in the main package triggered +// golang.org/issue/18250 +func DeclaredInMain() { +} + +type C struct { +} + +func F() *C { + return nil +} + +var slicePtr interface{} = &[]int{} + +func main() { + defer depBase.ImplementedInAsm() + // This code below causes various go.itab.* symbols to be generated in + // the executable. Similar code in ../depBase/dep.go results in + // exercising https://golang.org/issues/17594 + reflect.TypeOf(os.Stdout).Elem() + runtime.GC() + depBase.V = depBase.F() + 1 + + var c *C + if reflect.TypeOf(F).Out(0) != reflect.TypeOf(c) { + panic("bad reflection results, see golang.org/issue/18252") + } + + sp := reflect.New(reflect.TypeOf(slicePtr).Elem()) + s := sp.Interface() + + if reflect.TypeOf(s) != reflect.TypeOf(slicePtr) { + panic("bad reflection results, see golang.org/issue/18729") + } +} diff --git a/libgo/misc/cgo/testshared/testdata/exe2/exe2.go b/libgo/misc/cgo/testshared/testdata/exe2/exe2.go new file mode 100644 index 0000000..433f331 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/exe2/exe2.go @@ -0,0 +1,8 @@ +package main + +import "testshared/dep2" + +func main() { + d := &dep2.Dep2{} + dep2.W = dep2.G() + 1 + d.Method() +} diff --git a/libgo/misc/cgo/testshared/testdata/exe3/exe3.go b/libgo/misc/cgo/testshared/testdata/exe3/exe3.go new file mode 100644 index 0000000..533e3a9e --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/exe3/exe3.go @@ -0,0 +1,7 @@ +package main + +import "testshared/dep3" + +func main() { + dep3.D3() +} diff --git a/libgo/misc/cgo/testshared/testdata/execgo/exe.go b/libgo/misc/cgo/testshared/testdata/execgo/exe.go new file mode 100644 index 0000000..0427be8 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/execgo/exe.go @@ -0,0 +1,8 @@ +package main + +/* + */ +import "C" + +func main() { +} diff --git a/libgo/misc/cgo/testshared/testdata/explicit/explicit.go b/libgo/misc/cgo/testshared/testdata/explicit/explicit.go new file mode 100644 index 0000000..af969fc --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/explicit/explicit.go @@ -0,0 +1,9 @@ +package explicit + +import ( + "testshared/implicit" +) + +func E() int { + return implicit.I() +} diff --git a/libgo/misc/cgo/testshared/testdata/global/main.go b/libgo/misc/cgo/testshared/testdata/global/main.go new file mode 100644 index 0000000..f43e7c3 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/global/main.go @@ -0,0 +1,71 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "testshared/globallib" +) + +//go:noinline +func testLoop() { + for i, s := range globallib.Data { + if s != int64(i) { + panic("testLoop: mismatch") + } + } +} + +//go:noinline +func ptrData() *[1<<20 + 10]int64 { + return &globallib.Data +} + +//go:noinline +func testMediumOffset() { + for i, s := range globallib.Data[1<<16-2:] { + if s != int64(i)+1<<16-2 { + panic("testMediumOffset: index mismatch") + } + } + + x := globallib.Data[1<<16-1] + if x != 1<<16-1 { + panic("testMediumOffset: direct mismatch") + } + + y := &globallib.Data[1<<16-3] + if y != &ptrData()[1<<16-3] { + panic("testMediumOffset: address mismatch") + } +} + +//go:noinline +func testLargeOffset() { + for i, s := range globallib.Data[1<<20:] { + if s != int64(i)+1<<20 { + panic("testLargeOffset: index mismatch") + } + } + + x := globallib.Data[1<<20+1] + if x != 1<<20+1 { + panic("testLargeOffset: direct mismatch") + } + + y := &globallib.Data[1<<20+2] + if y != &ptrData()[1<<20+2] { + panic("testLargeOffset: address mismatch") + } +} + +func main() { + testLoop() + + // SSA rules commonly merge offsets into addresses. These + // tests access global data in different ways to try + // and exercise different SSA rules. + testMediumOffset() + testLargeOffset() +} diff --git a/libgo/misc/cgo/testshared/testdata/globallib/global.go b/libgo/misc/cgo/testshared/testdata/globallib/global.go new file mode 100644 index 0000000..b4372a2 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/globallib/global.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package globallib + +// Data is large enough to that offsets into it do not fit into +// 16-bit or 20-bit immediates. Ideally we'd also try and overrun +// 32-bit immediates, but that requires the test machine to have +// too much memory. +var Data [1<<20 + 10]int64 + +func init() { + for i := range Data { + Data[i] = int64(i) + } +} diff --git a/libgo/misc/cgo/testshared/testdata/iface/main.go b/libgo/misc/cgo/testshared/testdata/iface/main.go new file mode 100644 index 0000000..d26ebbc --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/iface/main.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "testshared/iface_a" +import "testshared/iface_b" + +func main() { + if iface_a.F() != iface_b.F() { + panic("empty interfaces not equal") + } + if iface_a.G() != iface_b.G() { + panic("non-empty interfaces not equal") + } +} diff --git a/libgo/misc/cgo/testshared/testdata/iface_a/a.go b/libgo/misc/cgo/testshared/testdata/iface_a/a.go new file mode 100644 index 0000000..e2cef1e --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/iface_a/a.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iface_a + +import "testshared/iface_i" + +//go:noinline +func F() interface{} { + return (*iface_i.T)(nil) +} + +//go:noinline +func G() iface_i.I { + return (*iface_i.T)(nil) +} diff --git a/libgo/misc/cgo/testshared/testdata/iface_b/b.go b/libgo/misc/cgo/testshared/testdata/iface_b/b.go new file mode 100644 index 0000000..dd3e027 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/iface_b/b.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iface_b + +import "testshared/iface_i" + +//go:noinline +func F() interface{} { + return (*iface_i.T)(nil) +} + +//go:noinline +func G() iface_i.I { + return (*iface_i.T)(nil) +} diff --git a/libgo/misc/cgo/testshared/testdata/iface_i/i.go b/libgo/misc/cgo/testshared/testdata/iface_i/i.go new file mode 100644 index 0000000..31c8038 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/iface_i/i.go @@ -0,0 +1,17 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iface_i + +type I interface { + M() +} + +type T struct { +} + +func (t *T) M() { +} + +// *T implements I diff --git a/libgo/misc/cgo/testshared/testdata/implicit/implicit.go b/libgo/misc/cgo/testshared/testdata/implicit/implicit.go new file mode 100644 index 0000000..5360188 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/implicit/implicit.go @@ -0,0 +1,5 @@ +package implicit + +func I() int { + return 42 +} diff --git a/libgo/misc/cgo/testshared/testdata/implicitcmd/implicitcmd.go b/libgo/misc/cgo/testshared/testdata/implicitcmd/implicitcmd.go new file mode 100644 index 0000000..4d42967 --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/implicitcmd/implicitcmd.go @@ -0,0 +1,10 @@ +package main + +import ( + "testshared/explicit" + "testshared/implicit" +) + +func main() { + println(implicit.I() + explicit.E()) +} diff --git a/libgo/misc/cgo/testshared/testdata/issue25065/a.go b/libgo/misc/cgo/testshared/testdata/issue25065/a.go new file mode 100644 index 0000000..979350f --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/issue25065/a.go @@ -0,0 +1,20 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package issue25065 has a type with a method that is +// 1) referenced in a method expression +// 2) not called +// 3) not converted to an interface +// 4) is a value method but the reference is to the pointer method +// These cases avoid the call to makefuncsym from typecheckfunc, but we +// still need to call makefuncsym somehow or the symbol will not be defined. +package issue25065 + +type T int + +func (t T) M() {} + +func F() func(*T) { + return (*T).M +} diff --git a/libgo/misc/cgo/testshared/testdata/trivial/trivial.go b/libgo/misc/cgo/testshared/testdata/trivial/trivial.go new file mode 100644 index 0000000..6ade47c --- /dev/null +++ b/libgo/misc/cgo/testshared/testdata/trivial/trivial.go @@ -0,0 +1,9 @@ +package main + +func main() { + // This is enough to make sure that the executable references + // a type descriptor, which was the cause of + // https://golang.org/issue/25970. + c := make(chan int) + _ = c +} diff --git a/libgo/misc/cgo/testso/cgoso.c b/libgo/misc/cgo/testso/cgoso.c deleted file mode 100644 index 917f472..0000000 --- a/libgo/misc/cgo/testso/cgoso.c +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "_cgo_export.h" - -#ifdef WIN32 -extern void setCallback(void *); -void init() { - setCallback(goCallback); -} -#else -void init() {} -#endif diff --git a/libgo/misc/cgo/testso/cgoso.go b/libgo/misc/cgo/testso/cgoso.go deleted file mode 100644 index 29814fa..0000000 --- a/libgo/misc/cgo/testso/cgoso.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgosotest - -/* -// intentionally write the same LDFLAGS differently -// to test correct handling of LDFLAGS. -#cgo linux LDFLAGS: -L. -lcgosotest -#cgo dragonfly LDFLAGS: -L. -l cgosotest -#cgo freebsd LDFLAGS: -L. -l cgosotest -#cgo openbsd LDFLAGS: -L. -l cgosotest -#cgo solaris LDFLAGS: -L. -lcgosotest -#cgo netbsd LDFLAGS: -L. libcgosotest.so -#cgo darwin LDFLAGS: -L. libcgosotest.dylib -#cgo windows LDFLAGS: -L. libcgosotest.dll - -void init(void); -void sofunc(void); -*/ -import "C" - -func Test() { - C.init() - C.sofunc() -} - -//export goCallback -func goCallback() { -} diff --git a/libgo/misc/cgo/testso/cgoso_c.c b/libgo/misc/cgo/testso/cgoso_c.c deleted file mode 100644 index 7a38022..0000000 --- a/libgo/misc/cgo/testso/cgoso_c.c +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -#ifdef WIN32 -// A Windows DLL is unable to call an arbitrary function in -// the main executable. Work around that by making the main -// executable pass the callback function pointer to us. -void (*goCallback)(void); -__declspec(dllexport) void setCallback(void *f) -{ - goCallback = (void (*)())f; -} -__declspec(dllexport) void sofunc(void); -#else -extern void goCallback(void); -void setCallback(void *f) { (void)f; } -#endif - -// OpenBSD and older Darwin lack TLS support -#if !defined(__OpenBSD__) && !defined(__APPLE__) -__thread int tlsvar = 12345; -#endif - -void sofunc(void) -{ - goCallback(); -} diff --git a/libgo/misc/cgo/testso/cgoso_unix.go b/libgo/misc/cgo/testso/cgoso_unix.go deleted file mode 100644 index 49cdeaa..0000000 --- a/libgo/misc/cgo/testso/cgoso_unix.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build dragonfly freebsd linux netbsd solaris - -package cgosotest - -/* -extern int __thread tlsvar; -int *getTLS() { return &tlsvar; } -*/ -import "C" - -func init() { - if v := *C.getTLS(); v != 12345 { - println("got", v) - panic("BAD TLS value") - } -} diff --git a/libgo/misc/cgo/testso/main.go b/libgo/misc/cgo/testso/main.go deleted file mode 100644 index 88aa432..0000000 --- a/libgo/misc/cgo/testso/main.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import "." - -func main() { - cgosotest.Test() -} diff --git a/libgo/misc/cgo/testso/noso_test.go b/libgo/misc/cgo/testso/noso_test.go new file mode 100644 index 0000000..c88aebf --- /dev/null +++ b/libgo/misc/cgo/testso/noso_test.go @@ -0,0 +1,9 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !cgo + +package so_test + +// Nothing to test. diff --git a/libgo/misc/cgo/testso/overlaydir_test.go b/libgo/misc/cgo/testso/overlaydir_test.go new file mode 100644 index 0000000..10c874d --- /dev/null +++ b/libgo/misc/cgo/testso/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package so_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testso/so_test.go b/libgo/misc/cgo/testso/so_test.go new file mode 100644 index 0000000..9c7f272 --- /dev/null +++ b/libgo/misc/cgo/testso/so_test.go @@ -0,0 +1,140 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build cgo + +package so_test + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func requireTestSOSupported(t *testing.T) { + t.Helper() + switch runtime.GOARCH { + case "arm", "arm64": + if runtime.GOOS == "darwin" { + t.Skip("No exec facility on iOS.") + } + case "ppc64": + if runtime.GOOS == "linux" { + t.Skip("External linking not implemented on aix/ppc64 (issue #8912).") + } + case "mips64le", "mips64": + t.Skip("External linking not implemented on mips64.") + } + if runtime.GOOS == "android" { + t.Skip("No exec facility on Android.") + } +} + +func TestSO(t *testing.T) { + requireTestSOSupported(t) + + GOPATH, err := ioutil.TempDir("", "cgosotest") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(GOPATH) + + modRoot := filepath.Join(GOPATH, "src", "cgosotest") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil { + log.Panic(err) + } + + cmd := exec.Command("go", "env", "CC", "GOGCCFLAGS") + cmd.Dir = modRoot + cmd.Stderr = new(strings.Builder) + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err := cmd.Output() + if err != nil { + t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + } + lines := strings.Split(string(out), "\n") + if len(lines) != 3 || lines[2] != "" { + t.Fatalf("Unexpected output from %s:\n%s", strings.Join(cmd.Args, " "), lines) + } + + cc := lines[0] + if cc == "" { + t.Fatal("CC environment variable (go env CC) cannot be empty") + } + gogccflags := strings.Split(lines[1], " ") + + // build shared object + ext := "so" + args := append(gogccflags, "-shared") + switch runtime.GOOS { + case "darwin": + ext = "dylib" + args = append(args, "-undefined", "suppress", "-flat_namespace") + case "windows": + ext = "dll" + args = append(args, "-DEXPORT_DLL") + case "aix": + ext = "so.1" + } + sofname := "libcgosotest." + ext + args = append(args, "-o", sofname, "cgoso_c.c") + + cmd = exec.Command(cc, args...) + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + + if runtime.GOOS == "aix" { + // Shared object must be wrapped by an archive + cmd = exec.Command("ar", "-X64", "-q", "libcgosotest.a", "libcgosotest.so.1") + cmd.Dir = modRoot + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + } + + cmd = exec.Command("go", "build", "-o", "main.exe", "main.go") + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + + cmd = exec.Command("./main.exe") + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + if runtime.GOOS != "windows" { + s := "LD_LIBRARY_PATH" + if runtime.GOOS == "darwin" { + s = "DYLD_LIBRARY_PATH" + } + cmd.Env = append(os.Environ(), s+"=.") + + // On FreeBSD 64-bit architectures, the 32-bit linker looks for + // different environment variables. + if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { + cmd.Env = append(cmd.Env, "LD_32_LIBRARY_PATH=.") + } + } + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) +} diff --git a/libgo/misc/cgo/testso/testdata/cgoso.c b/libgo/misc/cgo/testso/testdata/cgoso.c new file mode 100644 index 0000000..612e5d3 --- /dev/null +++ b/libgo/misc/cgo/testso/testdata/cgoso.c @@ -0,0 +1,14 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "_cgo_export.h" + +#if defined(WIN32) || defined(_AIX) +extern void setCallback(void *); +void init() { + setCallback(goCallback); +} +#else +void init() {} +#endif diff --git a/libgo/misc/cgo/testso/testdata/cgoso.go b/libgo/misc/cgo/testso/testdata/cgoso.go new file mode 100644 index 0000000..bba5de3 --- /dev/null +++ b/libgo/misc/cgo/testso/testdata/cgoso.go @@ -0,0 +1,32 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgosotest + +/* +// intentionally write the same LDFLAGS differently +// to test correct handling of LDFLAGS. +#cgo linux LDFLAGS: -L. -lcgosotest +#cgo dragonfly LDFLAGS: -L. -l cgosotest +#cgo freebsd LDFLAGS: -L. -l cgosotest +#cgo openbsd LDFLAGS: -L. -l cgosotest +#cgo solaris LDFLAGS: -L. -lcgosotest +#cgo netbsd LDFLAGS: -L. libcgosotest.so +#cgo darwin LDFLAGS: -L. libcgosotest.dylib +#cgo windows LDFLAGS: -L. libcgosotest.dll +#cgo aix LDFLAGS: -L. -l cgosotest + +void init(void); +void sofunc(void); +*/ +import "C" + +func Test() { + C.init() + C.sofunc() +} + +//export goCallback +func goCallback() { +} diff --git a/libgo/misc/cgo/testso/testdata/cgoso_c.c b/libgo/misc/cgo/testso/testdata/cgoso_c.c new file mode 100644 index 0000000..e5015ed --- /dev/null +++ b/libgo/misc/cgo/testso/testdata/cgoso_c.c @@ -0,0 +1,39 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +#ifdef WIN32 +// A Windows DLL is unable to call an arbitrary function in +// the main executable. Work around that by making the main +// executable pass the callback function pointer to us. +void (*goCallback)(void); +__declspec(dllexport) void setCallback(void *f) +{ + goCallback = (void (*)())f; +} +__declspec(dllexport) void sofunc(void); +#elif defined(_AIX) +// AIX doesn't allow the creation of a shared object with an +// undefined symbol. It's possible to bypass this problem by +// using -Wl,-G and -Wl,-brtl option which allows run-time linking. +// However, that's not how most of AIX shared object works. +// Therefore, it's better to consider goCallback as a pointer and +// to set up during an init function. +void (*goCallback)(void); +void setCallback(void *f) { goCallback = f; } +#else +extern void goCallback(void); +void setCallback(void *f) { (void)f; } +#endif + +// OpenBSD and older Darwin lack TLS support +#if !defined(__OpenBSD__) && !defined(__APPLE__) +__thread int tlsvar = 12345; +#endif + +void sofunc(void) +{ + goCallback(); +} diff --git a/libgo/misc/cgo/testso/testdata/cgoso_unix.go b/libgo/misc/cgo/testso/testdata/cgoso_unix.go new file mode 100644 index 0000000..1860694 --- /dev/null +++ b/libgo/misc/cgo/testso/testdata/cgoso_unix.go @@ -0,0 +1,20 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix dragonfly freebsd linux netbsd solaris + +package cgosotest + +/* +extern int __thread tlsvar; +int *getTLS() { return &tlsvar; } +*/ +import "C" + +func init() { + if v := *C.getTLS(); v != 12345 { + println("got", v) + panic("BAD TLS value") + } +} diff --git a/libgo/misc/cgo/testso/testdata/main.go b/libgo/misc/cgo/testso/testdata/main.go new file mode 100644 index 0000000..963d451 --- /dev/null +++ b/libgo/misc/cgo/testso/testdata/main.go @@ -0,0 +1,13 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import "cgosotest" + +func main() { + cgosotest.Test() +} diff --git a/libgo/misc/cgo/testsovar/cgoso.go b/libgo/misc/cgo/testsovar/cgoso.go deleted file mode 100644 index 88d44c2..0000000 --- a/libgo/misc/cgo/testsovar/cgoso.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgosotest - -// This test verifies that Go can access C variables -// in shared object file via cgo. - -/* -// intentionally write the same LDFLAGS differently -// to test correct handling of LDFLAGS. -#cgo windows CFLAGS: -DIMPORT_DLL -#cgo linux LDFLAGS: -L. -lcgosotest -#cgo dragonfly LDFLAGS: -L. -l cgosotest -#cgo freebsd LDFLAGS: -L. -l cgosotest -#cgo openbsd LDFLAGS: -L. -l cgosotest -#cgo solaris LDFLAGS: -L. -lcgosotest -#cgo netbsd LDFLAGS: -L. libcgosotest.so -#cgo darwin LDFLAGS: -L. libcgosotest.dylib -#cgo windows LDFLAGS: -L. libcgosotest.dll - -#include "cgoso_c.h" - -const char* getVar() { - return exported_var; -} -*/ -import "C" - -import "fmt" - -func Test() { - const want = "Hello world" - got := C.GoString(C.getVar()) - if got != want { - panic(fmt.Sprintf("testExportedVar: got %q, but want %q", got, want)) - } - got = C.GoString(C.exported_var) - if got != want { - panic(fmt.Sprintf("testExportedVar: got %q, but want %q", got, want)) - } -} diff --git a/libgo/misc/cgo/testsovar/cgoso_c.c b/libgo/misc/cgo/testsovar/cgoso_c.c deleted file mode 100644 index a448c01..0000000 --- a/libgo/misc/cgo/testsovar/cgoso_c.c +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -const char *exported_var = "Hello world"; diff --git a/libgo/misc/cgo/testsovar/cgoso_c.h b/libgo/misc/cgo/testsovar/cgoso_c.h deleted file mode 100644 index 640db7b..0000000 --- a/libgo/misc/cgo/testsovar/cgoso_c.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -#ifdef WIN32 -#if defined(EXPORT_DLL) -# define VAR __declspec(dllexport) -#elif defined(IMPORT_DLL) -# define VAR __declspec(dllimport) -#endif -#else -# define VAR extern -#endif - -VAR const char *exported_var; diff --git a/libgo/misc/cgo/testsovar/main.go b/libgo/misc/cgo/testsovar/main.go deleted file mode 100644 index 9c8a1c4..0000000 --- a/libgo/misc/cgo/testsovar/main.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package main - -import "." - -func main() { - cgosotest.Test() -} diff --git a/libgo/misc/cgo/testsovar/noso_test.go b/libgo/misc/cgo/testsovar/noso_test.go new file mode 100644 index 0000000..c88aebf --- /dev/null +++ b/libgo/misc/cgo/testsovar/noso_test.go @@ -0,0 +1,9 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !cgo + +package so_test + +// Nothing to test. diff --git a/libgo/misc/cgo/testsovar/overlaydir_test.go b/libgo/misc/cgo/testsovar/overlaydir_test.go new file mode 100644 index 0000000..10c874d --- /dev/null +++ b/libgo/misc/cgo/testsovar/overlaydir_test.go @@ -0,0 +1,81 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package so_test + +import ( + "io" + "os" + "path/filepath" + "strings" +) + +// overlayDir makes a minimal-overhead copy of srcRoot in which new files may be added. +// +// TODO: Once we no longer need to support the misc module in GOPATH mode, +// factor this function out into a package to reduce duplication. +func overlayDir(dstRoot, srcRoot string) error { + dstRoot = filepath.Clean(dstRoot) + if err := os.MkdirAll(dstRoot, 0777); err != nil { + return err + } + + symBase, err := filepath.Rel(srcRoot, dstRoot) + if err != nil { + symBase, err = filepath.Abs(srcRoot) + if err != nil { + return err + } + } + + return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { + if err != nil || srcPath == srcRoot { + return err + } + + suffix := strings.TrimPrefix(srcPath, srcRoot) + for len(suffix) > 0 && suffix[0] == filepath.Separator { + suffix = suffix[1:] + } + dstPath := filepath.Join(dstRoot, suffix) + + perm := info.Mode() & os.ModePerm + if info.Mode()&os.ModeSymlink != 0 { + info, err = os.Stat(srcPath) + if err != nil { + return err + } + perm = info.Mode() & os.ModePerm + } + + // Always copy directories (don't symlink them). + // If we add a file in the overlay, we don't want to add it in the original. + if info.IsDir() { + return os.Mkdir(dstPath, perm) + } + + // If the OS supports symlinks, use them instead of copying bytes. + if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + return nil + } + + // Otherwise, copy the bytes. + src, err := os.Open(srcPath) + if err != nil { + return err + } + defer src.Close() + + dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) + if err != nil { + return err + } + + _, err = io.Copy(dst, src) + if closeErr := dst.Close(); err == nil { + err = closeErr + } + return err + }) +} diff --git a/libgo/misc/cgo/testsovar/so_test.go b/libgo/misc/cgo/testsovar/so_test.go new file mode 100644 index 0000000..9c7f272 --- /dev/null +++ b/libgo/misc/cgo/testsovar/so_test.go @@ -0,0 +1,140 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build cgo + +package so_test + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func requireTestSOSupported(t *testing.T) { + t.Helper() + switch runtime.GOARCH { + case "arm", "arm64": + if runtime.GOOS == "darwin" { + t.Skip("No exec facility on iOS.") + } + case "ppc64": + if runtime.GOOS == "linux" { + t.Skip("External linking not implemented on aix/ppc64 (issue #8912).") + } + case "mips64le", "mips64": + t.Skip("External linking not implemented on mips64.") + } + if runtime.GOOS == "android" { + t.Skip("No exec facility on Android.") + } +} + +func TestSO(t *testing.T) { + requireTestSOSupported(t) + + GOPATH, err := ioutil.TempDir("", "cgosotest") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(GOPATH) + + modRoot := filepath.Join(GOPATH, "src", "cgosotest") + if err := overlayDir(modRoot, "testdata"); err != nil { + log.Panic(err) + } + if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module cgosotest\n"), 0666); err != nil { + log.Panic(err) + } + + cmd := exec.Command("go", "env", "CC", "GOGCCFLAGS") + cmd.Dir = modRoot + cmd.Stderr = new(strings.Builder) + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err := cmd.Output() + if err != nil { + t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + } + lines := strings.Split(string(out), "\n") + if len(lines) != 3 || lines[2] != "" { + t.Fatalf("Unexpected output from %s:\n%s", strings.Join(cmd.Args, " "), lines) + } + + cc := lines[0] + if cc == "" { + t.Fatal("CC environment variable (go env CC) cannot be empty") + } + gogccflags := strings.Split(lines[1], " ") + + // build shared object + ext := "so" + args := append(gogccflags, "-shared") + switch runtime.GOOS { + case "darwin": + ext = "dylib" + args = append(args, "-undefined", "suppress", "-flat_namespace") + case "windows": + ext = "dll" + args = append(args, "-DEXPORT_DLL") + case "aix": + ext = "so.1" + } + sofname := "libcgosotest." + ext + args = append(args, "-o", sofname, "cgoso_c.c") + + cmd = exec.Command(cc, args...) + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + + if runtime.GOOS == "aix" { + // Shared object must be wrapped by an archive + cmd = exec.Command("ar", "-X64", "-q", "libcgosotest.a", "libcgosotest.so.1") + cmd.Dir = modRoot + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + } + + cmd = exec.Command("go", "build", "-o", "main.exe", "main.go") + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) + + cmd = exec.Command("./main.exe") + cmd.Dir = modRoot + cmd.Env = append(os.Environ(), "GOPATH="+GOPATH) + if runtime.GOOS != "windows" { + s := "LD_LIBRARY_PATH" + if runtime.GOOS == "darwin" { + s = "DYLD_LIBRARY_PATH" + } + cmd.Env = append(os.Environ(), s+"=.") + + // On FreeBSD 64-bit architectures, the 32-bit linker looks for + // different environment variables. + if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { + cmd.Env = append(cmd.Env, "LD_32_LIBRARY_PATH=.") + } + } + out, err = cmd.CombinedOutput() + if err != nil { + t.Fatalf("%s: %s\n%s", strings.Join(cmd.Args, " "), err, out) + } + t.Logf("%s:\n%s", strings.Join(cmd.Args, " "), out) +} diff --git a/libgo/misc/cgo/testsovar/testdata/cgoso.go b/libgo/misc/cgo/testsovar/testdata/cgoso.go new file mode 100644 index 0000000..9c7f95e --- /dev/null +++ b/libgo/misc/cgo/testsovar/testdata/cgoso.go @@ -0,0 +1,44 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cgosotest + +// This test verifies that Go can access C variables +// in shared object file via cgo. + +/* +// intentionally write the same LDFLAGS differently +// to test correct handling of LDFLAGS. +#cgo windows CFLAGS: -DIMPORT_DLL +#cgo linux LDFLAGS: -L. -lcgosotest +#cgo dragonfly LDFLAGS: -L. -l cgosotest +#cgo freebsd LDFLAGS: -L. -l cgosotest +#cgo openbsd LDFLAGS: -L. -l cgosotest +#cgo solaris LDFLAGS: -L. -lcgosotest +#cgo netbsd LDFLAGS: -L. libcgosotest.so +#cgo darwin LDFLAGS: -L. libcgosotest.dylib +#cgo windows LDFLAGS: -L. libcgosotest.dll +#cgo aix LDFLAGS: -L. -l cgosotest + +#include "cgoso_c.h" + +const char* getVar() { + return exported_var; +} +*/ +import "C" + +import "fmt" + +func Test() { + const want = "Hello world" + got := C.GoString(C.getVar()) + if got != want { + panic(fmt.Sprintf("testExportedVar: got %q, but want %q", got, want)) + } + got = C.GoString(C.exported_var) + if got != want { + panic(fmt.Sprintf("testExportedVar: got %q, but want %q", got, want)) + } +} diff --git a/libgo/misc/cgo/testsovar/testdata/cgoso_c.c b/libgo/misc/cgo/testsovar/testdata/cgoso_c.c new file mode 100644 index 0000000..a448c01 --- /dev/null +++ b/libgo/misc/cgo/testsovar/testdata/cgoso_c.c @@ -0,0 +1,7 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +const char *exported_var = "Hello world"; diff --git a/libgo/misc/cgo/testsovar/testdata/cgoso_c.h b/libgo/misc/cgo/testsovar/testdata/cgoso_c.h new file mode 100644 index 0000000..640db7b --- /dev/null +++ b/libgo/misc/cgo/testsovar/testdata/cgoso_c.h @@ -0,0 +1,17 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +#ifdef WIN32 +#if defined(EXPORT_DLL) +# define VAR __declspec(dllexport) +#elif defined(IMPORT_DLL) +# define VAR __declspec(dllimport) +#endif +#else +# define VAR extern +#endif + +VAR const char *exported_var; diff --git a/libgo/misc/cgo/testsovar/testdata/main.go b/libgo/misc/cgo/testsovar/testdata/main.go new file mode 100644 index 0000000..87b52cef --- /dev/null +++ b/libgo/misc/cgo/testsovar/testdata/main.go @@ -0,0 +1,13 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package main + +import "cgosotest" + +func main() { + cgosotest.Test() +} -- cgit v1.1