1
2
3
4
5
6
7
8
9
10
11 package cgotest
12
13 import (
14 "internal/runtime/sys"
15 "runtime"
16 "runtime/cgo"
17 "runtime/debug"
18 "strings"
19 "sync"
20 "sync/atomic"
21 "testing"
22 "unsafe"
23 )
24
25
123 import "C"
124
125
126
127
128 func ReturnIntLong() (int, C.long) {
129 return 1, 2
130 }
131
132
133 func gc() {
134 runtime.GC()
135 }
136
137
138
139 var sum struct {
140 sync.Mutex
141 i int
142 }
143
144
145 func Add(x int) {
146 defer func() {
147 recover()
148 }()
149 sum.Lock()
150 sum.i += x
151 sum.Unlock()
152 var p *int
153 *p = 2
154 }
155
156
157 func goDummy() {
158 }
159
160 func testCthread(t *testing.T) {
161 if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && runtime.GOARCH == "arm64" {
162 t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
163 }
164 sum.i = 0
165 C.doAdd(10, 6)
166
167 want := 10 * (10 - 1) / 2 * 6
168 if sum.i != want {
169 t.Fatalf("sum=%d, want %d", sum.i, want)
170 }
171 }
172
173
174
175 func benchCGoInCthread(b *testing.B) {
176 n := C.callGoInCThread(C.int(b.N))
177 if int(n) != b.N {
178 b.Fatal("unmatch loop times")
179 }
180 }
181
182
183
184
185 func BackIntoGo() {
186 x := 1
187
188 for i := 0; i < 10000; i++ {
189 xvariadic(x)
190 if x != 1 {
191 panic("x is not 1?")
192 }
193 }
194 }
195
196 func xvariadic(x ...interface{}) {
197 }
198
199 func test1328(t *testing.T) {
200 C.IntoC()
201 }
202
203
204
205
206 var (
207 issue1560 int32
208
209 issue1560Ch = make(chan bool, 2)
210 )
211
212
213 func Issue1560FromC() {
214 for atomic.LoadInt32(&issue1560) != 1 {
215 runtime.Gosched()
216 }
217 atomic.AddInt32(&issue1560, 1)
218 for atomic.LoadInt32(&issue1560) != 3 {
219 runtime.Gosched()
220 }
221 issue1560Ch <- true
222 }
223
224 func Issue1560FromGo() {
225 atomic.AddInt32(&issue1560, 1)
226 for atomic.LoadInt32(&issue1560) != 2 {
227 runtime.Gosched()
228 }
229 atomic.AddInt32(&issue1560, 1)
230 issue1560Ch <- true
231 }
232
233 func test1560(t *testing.T) {
234 go Issue1560FromGo()
235 go C.Issue1560InC()
236 <-issue1560Ch
237 <-issue1560Ch
238 }
239
240
241
242
243 func exportbyte() byte {
244 return 0
245 }
246
247
248 func exportbool() bool {
249 return false
250 }
251
252
253 func exportrune() rune {
254 return 0
255 }
256
257
258 func exporterror() error {
259 return nil
260 }
261
262
263 func exportint() int {
264 return 0
265 }
266
267
268 func exportuint() uint {
269 return 0
270 }
271
272
273 func exportuintptr() uintptr {
274 return (uintptr)(0)
275 }
276
277
278 func exportint8() int8 {
279 return 0
280 }
281
282
283 func exportuint8() uint8 {
284 return 0
285 }
286
287
288 func exportint16() int16 {
289 return 0
290 }
291
292
293 func exportuint16() uint16 {
294 return 0
295 }
296
297
298 func exportint32() int32 {
299 return 0
300 }
301
302
303 func exportuint32() uint32 {
304 return 0
305 }
306
307
308 func exportint64() int64 {
309 return 0
310 }
311
312
313 func exportuint64() uint64 {
314 return 0
315 }
316
317
318 func exportfloat32() float32 {
319 return 0
320 }
321
322
323 func exportfloat64() float64 {
324 return 0
325 }
326
327
328 func exportcomplex64() complex64 {
329 return 0
330 }
331
332
333 func exportcomplex128() complex128 {
334 return 0
335 }
336
337
338
339
340 func exportSliceIn(s []byte) bool {
341 return len(s) == cap(s)
342 }
343
344
345 func exportSliceOut() []byte {
346 return []byte{1}
347 }
348
349
350 func exportSliceInOut(s []byte) []byte {
351 return s
352 }
353
354
355
356 func init() {
357 if runtime.GOOS == "android" {
358 return
359 }
360
361
362
363
364 C.lockOSThreadC()
365 }
366
367 func test3775(t *testing.T) {
368 if runtime.GOOS == "android" {
369 return
370 }
371
372 C.lockOSThreadC()
373 }
374
375
376 func lockOSThreadCallback() {
377 runtime.LockOSThread()
378 runtime.UnlockOSThread()
379 go C.usleep(10000)
380 runtime.Gosched()
381 }
382
383
384
385 var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.II, C.J}
386
387
388 func issue5548FromC(s string, i int) int {
389 if len(s) == 4 && s == "test" && i == 42 {
390 return 12345
391 }
392 println("got", len(s), i)
393 return 9876
394 }
395
396 func test5548(t *testing.T) {
397 if x := C.issue5548_in_c(); x != 12345 {
398 t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
399 }
400 }
401
402
403
404
405 func GoIssue6833Func(aui uint, aui64 uint64) uint64 {
406 return aui64 + uint64(aui)
407 }
408
409 func test6833(t *testing.T) {
410 ui := 7
411 ull := uint64(0x4000300020001000)
412 v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull)))
413 exp := uint64(ui) + ull
414 if v != exp {
415 t.Errorf("issue6833Func() returns %x, expected %x", v, exp)
416 }
417 }
418
419
420
421 const CString = "C string"
422
423
424 func CheckIssue6907Go(s string) C.int {
425 if s == CString {
426 return 1
427 }
428 return 0
429 }
430
431 func test6907Go(t *testing.T) {
432 if got := C.CheckIssue6907C(CString); got != 1 {
433 t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
434 }
435 }
436
437
438
439 var bad7665 unsafe.Pointer = C.f7665
440 var good7665 uintptr = uintptr(C.f7665)
441
442 func test7665(t *testing.T) {
443 if bad7665 == nil || uintptr(bad7665) != good7665 {
444 t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
445 }
446 }
447
448
449
450 var issue7978sync uint32
451
452 func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
453 runtime.GC()
454 buf := make([]byte, 65536)
455 trace := string(buf[:runtime.Stack(buf, true)])
456 for goroutine := range strings.SplitSeq(trace, "\n\n") {
457 if strings.Contains(goroutine, "test.issue7978go") {
458 trace := strings.Split(goroutine, "\n")
459
460 for i := 0; i < depth; i++ {
461 if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
462 t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
463 return
464 }
465 if strings.Contains(trace[1+2*i], wantFunc) {
466 return
467 }
468 }
469 t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
470 return
471 }
472 }
473 t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
474 }
475
476 func issue7978wait(store uint32, wait uint32) {
477 if store != 0 {
478 atomic.StoreUint32(&issue7978sync, store)
479 }
480 for atomic.LoadUint32(&issue7978sync) != wait {
481 runtime.Gosched()
482 }
483 }
484
485
486 func issue7978cb() {
487
488
489 growStack(64)
490 issue7978wait(3, 4)
491 }
492
493 func growStack(n int) int {
494 var buf [128]int
495 if n == 0 {
496 return 0
497 }
498 return buf[growStack(n-1)]
499 }
500
501 func issue7978go() {
502 C.issue7978c((*C.uint32_t)(&issue7978sync))
503 issue7978wait(7, 8)
504 }
505
506 func test7978(t *testing.T) {
507 if runtime.Compiler == "gccgo" {
508 t.Skip("gccgo can not do stack traces of C code")
509 }
510 debug.SetTraceback("2")
511 issue7978sync = 0
512 go issue7978go()
513
514 issue7978wait(0, 1)
515 issue7978check(t, "_Cfunc_issue7978c(", "", 1)
516
517 issue7978wait(2, 3)
518 issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
519
520 issue7978wait(4, 5)
521 issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
522
523 issue7978wait(6, 7)
524 issue7978check(t, "test.issue7978go(", "", 3)
525 atomic.StoreUint32(&issue7978sync, 8)
526 }
527
528
529
530 var issue8331Var C.issue8331
531
532
533
534
535 func Test8945() {
536 _ = C.func8945
537 }
538
539
540
541
542 func multi() (*C.char, C.int) {
543 return C.CString("multi"), 0
544 }
545
546 func test20910(t *testing.T) {
547 C.callMulti()
548 }
549
550
551
552 const issue28772Constant2 = C.issue28772Constant2
553
554
555
556
557 func useIssue31891A(c *C.Issue31891A) {}
558
559
560 func useIssue31891B(c *C.Issue31891B) {}
561
562 func test31891(t *testing.T) {
563 C.callIssue31891()
564 }
565
566
567
568 var issue37033 = 42
569
570
571 func GoFunc37033(handle C.uintptr_t) {
572 h := cgo.Handle(handle)
573 ch := h.Value().(chan int)
574 ch <- issue37033
575 }
576
577
578
579
580 var _ C.PIssue38408 = &C.Issue38408{i: 1}
581
582
583
584
585
586
587
588 func Issue44648A(issue44648F C.issue44648F, data unsafe.Pointer) C.int {
589 return 0
590 }
591
592
593 func Issue44648B(issue44648T C.issue44648T) (C.issue44648T, C.issue44648T) {
594 return issue44648T, issue44648T
595 }
596
597
598 func Issue44648C(r C.int) (a, b C.int) {
599 return r, r
600 }
601
602
603
604 type data49633 struct {
605 msg string
606 }
607
608
609 func GoFunc49633(context unsafe.Pointer) {
610 h := *(*cgo.Handle)(context)
611 v := h.Value().(*data49633)
612 v.msg = "hello"
613 }
614
615 func test49633(t *testing.T) {
616 v := &data49633{}
617 h := cgo.NewHandle(v)
618 defer h.Delete()
619 C.cfunc49633(unsafe.Pointer(&h))
620 if v.msg != "hello" {
621 t.Errorf("msg = %q, want 'hello'", v.msg)
622 }
623 }
624
625
626 func exportAny76340Param(obj any) C.int {
627 if obj == nil {
628 return 0
629 }
630
631 return 1
632 }
633
634
635 func exportAny76340Return(val C.int) any {
636 if val == 0 {
637 return nil
638 }
639
640 return int(val)
641 }
642
643
644 func ditCallback() uint8 {
645 if sys.DITEnabled() {
646 return 1
647 }
648 return 0
649 }
650
651
652
653
654
655 var callbackInInitVar int
656
657 func init() {
658 C.callbackInInitC()
659 callbackInInitVar = 123
660 }
661
662 var callbackInInitChan = make(chan int)
663
664
665 func callbackInInit() {
666 if callbackInInitVar != 123 {
667 panic("callbackInInitVar not initialized to 123")
668 }
669 callbackInInitChan <- 1
670 }
671
672 func testCallbackInInit(t *testing.T) {
673 <-callbackInInitChan
674 }
675
View as plain text