File tree 2 files changed +33
-2
lines changed
2 files changed +33
-2
lines changed Original file line number Diff line number Diff line change @@ -19,6 +19,7 @@ import (
19
19
"strconv"
20
20
"strings"
21
21
"sync"
22
+ "sync/atomic"
22
23
"testing"
23
24
"time"
24
25
"unicode"
@@ -1546,6 +1547,30 @@ func TestCallWithStruct(t *testing.T) {
1546
1547
}
1547
1548
}
1548
1549
1550
+ func TestCallReturnsEmpty (t * testing.T ) {
1551
+ // Issue 21717: past-the-end pointer write in Call with
1552
+ // nonzero-sized frame and zero-sized return value.
1553
+ runtime .GC ()
1554
+ var finalized uint32
1555
+ f := func () (emptyStruct , * int ) {
1556
+ i := new (int )
1557
+ runtime .SetFinalizer (i , func (* int ) { atomic .StoreUint32 (& finalized , 1 ) })
1558
+ return emptyStruct {}, i
1559
+ }
1560
+ v := ValueOf (f ).Call (nil )[0 ] // out[0] should not alias out[1]'s memory, so the finalizer should run.
1561
+ timeout := time .After (5 * time .Second )
1562
+ for atomic .LoadUint32 (& finalized ) == 0 {
1563
+ select {
1564
+ case <- timeout :
1565
+ t .Fatal ("finalizer did not run" )
1566
+ default :
1567
+ }
1568
+ runtime .Gosched ()
1569
+ runtime .GC ()
1570
+ }
1571
+ runtime .KeepAlive (v )
1572
+ }
1573
+
1549
1574
func BenchmarkCall (b * testing.B ) {
1550
1575
fv := ValueOf (func (a , b string ) {})
1551
1576
b .ReportAllocs ()
Original file line number Diff line number Diff line change @@ -456,8 +456,14 @@ func (v Value) call(op string, in []Value) []Value {
456
456
tv := t .Out (i )
457
457
a := uintptr (tv .Align ())
458
458
off = (off + a - 1 ) &^ (a - 1 )
459
- fl := flagIndir | flag (tv .Kind ())
460
- ret [i ] = Value {tv .common (), unsafe .Pointer (uintptr (args ) + off ), fl }
459
+ if tv .Size () != 0 {
460
+ fl := flagIndir | flag (tv .Kind ())
461
+ ret [i ] = Value {tv .common (), unsafe .Pointer (uintptr (args ) + off ), fl }
462
+ } else {
463
+ // For zero-sized return value, args+off may point to the next object.
464
+ // In this case, return the zero value instead.
465
+ ret [i ] = Zero (tv )
466
+ }
461
467
off += tv .Size ()
462
468
}
463
469
}
You can’t perform that action at this time.
0 commit comments