@@ -363,7 +363,7 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ
363
363
}
364
364
365
365
case "new" :
366
- alloc := emitNew (fn , deref (typ ), pos )
366
+ alloc := emitNew (fn , mustDeref (typ ), pos )
367
367
alloc .Comment = "new"
368
368
return alloc
369
369
@@ -375,8 +375,8 @@ func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ
375
375
// been constant-folded.)
376
376
//
377
377
// Type parameters are always non-constant so use Underlying.
378
- t := deref (fn .typeOf (args [0 ])). Underlying ( )
379
- if at , ok := t .(* types.Array ); ok {
378
+ t , _ := deptr (fn .typeOf (args [0 ]))
379
+ if at , ok := t .Underlying (). (* types.Array ); ok {
380
380
b .expr (fn , args [0 ]) // for effects only
381
381
return intConst (at .Len ())
382
382
}
@@ -431,7 +431,7 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
431
431
return & address {addr : v , pos : e .Pos (), expr : e }
432
432
433
433
case * ast.CompositeLit :
434
- t := deref (fn .typeOf (e ))
434
+ t , _ := deptr (fn .typeOf (e ))
435
435
var v * Alloc
436
436
if escaping {
437
437
v = emitNew (fn , t , e .Lbrace )
@@ -459,7 +459,8 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
459
459
wantAddr := true
460
460
v := b .receiver (fn , e .X , wantAddr , escaping , sel )
461
461
index := sel .index [len (sel .index )- 1 ]
462
- fld := typeparams .CoreType (deref (v .Type ())).(* types.Struct ).Field (index )
462
+ dt , _ := deptr (v .Type ())
463
+ fld := typeparams .CoreType (dt ).(* types.Struct ).Field (index )
463
464
464
465
// Due to the two phases of resolving AssignStmt, a panic from x.f = p()
465
466
// when x is nil is required to come after the side-effects of
@@ -508,7 +509,7 @@ func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
508
509
v .setType (et )
509
510
return fn .emit (v )
510
511
}
511
- return & lazyAddress {addr : emit , t : deref (et ), pos : e .Lbrack , expr : e }
512
+ return & lazyAddress {addr : emit , t : mustDeref (et ), pos : e .Lbrack , expr : e }
512
513
513
514
case * ast.StarExpr :
514
515
return & address {addr : b .expr (fn , e .X ), pos : e .Star , expr : e }
@@ -554,7 +555,7 @@ func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *
554
555
// so if the type of the location is a pointer,
555
556
// an &-operation is implied.
556
557
if _ , ok := loc .(blank ); ! ok { // avoid calling blank.typ()
557
- if isPointer (loc .typ ()) {
558
+ if _ , ok := deptr (loc .typ ()); ok {
558
559
ptr := b .addr (fn , e , true ).address (fn )
559
560
// copy address
560
561
if sb != nil {
@@ -584,7 +585,7 @@ func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *
584
585
585
586
// Subtle: emit debug ref for aggregate types only;
586
587
// slice and map are handled by store ops in compLit.
587
- switch loc .typ ().Underlying ().(type ) {
588
+ switch loc .typ ().Underlying ().(type ) { // TODO(taking): check if Underlying() appropriate.
588
589
case * types.Struct , * types.Array :
589
590
emitDebugRef (fn , e , addr , true )
590
591
}
@@ -831,7 +832,7 @@ func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
831
832
// The result is a "bound".
832
833
obj := sel .obj .(* types.Func )
833
834
rt := fn .typ (recvType (obj ))
834
- wantAddr := isPointer (rt )
835
+ _ , wantAddr := deptr (rt )
835
836
escaping := true
836
837
v := b .receiver (fn , e .X , wantAddr , escaping , sel )
837
838
@@ -958,8 +959,9 @@ func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
958
959
//
959
960
// escaping is defined as per builder.addr().
960
961
func (b * builder ) receiver (fn * Function , e ast.Expr , wantAddr , escaping bool , sel * selection ) Value {
962
+
961
963
var v Value
962
- if wantAddr && ! sel .indirect && ! isPointer ( fn . typeOf ( e )) {
964
+ if _ , eptr := deptr ( fn . typeOf ( e )); wantAddr && ! sel .indirect && ! eptr {
963
965
v = b .addr (fn , e , escaping ).address (fn )
964
966
} else {
965
967
v = b .expr (fn , e )
@@ -968,7 +970,7 @@ func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, se
968
970
last := len (sel .index ) - 1
969
971
// The position of implicit selection is the position of the inducing receiver expression.
970
972
v = emitImplicitSelections (fn , v , sel .index [:last ], e .Pos ())
971
- if ! wantAddr && isPointer (v .Type ()) {
973
+ if _ , vptr := deptr (v .Type ()); ! wantAddr && vptr {
972
974
v = emitLoad (fn , v )
973
975
}
974
976
return v
@@ -987,7 +989,7 @@ func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
987
989
obj := sel .obj .(* types.Func )
988
990
recv := recvType (obj )
989
991
990
- wantAddr := isPointer (recv )
992
+ _ , wantAddr := deptr (recv )
991
993
escaping := true
992
994
v := b .receiver (fn , selector .X , wantAddr , escaping , sel )
993
995
if types .IsInterface (recv ) {
@@ -1253,8 +1255,10 @@ func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 {
1253
1255
// literal has type *T behaves like &T{}.
1254
1256
// In that case, addr must hold a T, not a *T.
1255
1257
func (b * builder ) compLit (fn * Function , addr Value , e * ast.CompositeLit , isZero bool , sb * storebuf ) {
1256
- typ := deref (fn .typeOf (e )) // type with name [may be type param]
1257
- t := deref (typeparams .CoreType (typ )).Underlying () // core type for comp lit case
1258
+ typ , _ := deptr (fn .typeOf (e )) // type with name [may be type param]
1259
+ t , _ := deptr (typeparams .CoreType (typ )) // core type for comp lit case
1260
+ t = t .Underlying ()
1261
+
1258
1262
// Computing typ and t is subtle as these handle pointer types.
1259
1263
// For example, &T{...} is valid even for maps and slices.
1260
1264
// Also typ should refer to T (not *T) while t should be the core type of T.
@@ -1282,7 +1286,8 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero
1282
1286
case * types.Struct :
1283
1287
if ! isZero && len (e .Elts ) != t .NumFields () {
1284
1288
// memclear
1285
- sb .store (& address {addr , e .Lbrace , nil }, zeroConst (deref (addr .Type ())))
1289
+ dt , _ := deptr (addr .Type ())
1290
+ sb .store (& address {addr , e .Lbrace , nil }, zeroConst (dt ))
1286
1291
isZero = true
1287
1292
}
1288
1293
for i , e := range e .Elts {
@@ -1326,7 +1331,8 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero
1326
1331
1327
1332
if ! isZero && int64 (len (e .Elts )) != at .Len () {
1328
1333
// memclear
1329
- sb .store (& address {array , e .Lbrace , nil }, zeroConst (deref (array .Type ())))
1334
+ dt , _ := deptr (array .Type ())
1335
+ sb .store (& address {array , e .Lbrace , nil }, zeroConst (dt ))
1330
1336
}
1331
1337
}
1332
1338
@@ -1379,8 +1385,13 @@ func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero
1379
1385
// map[*struct{}]bool{{}: true}
1380
1386
// An &-operation may be implied:
1381
1387
// map[*struct{}]bool{&struct{}{}: true}
1388
+ wantAddr := false
1389
+ if _ , ok := unparen (e .Key ).(* ast.CompositeLit ); ok {
1390
+ _ , wantAddr = t .Key ().Underlying ().(* types.Pointer )
1391
+ }
1392
+
1382
1393
var key Value
1383
- if _ , ok := unparen ( e . Key ).( * ast. CompositeLit ); ok && isPointer ( t . Key ()) {
1394
+ if wantAddr {
1384
1395
// A CompositeLit never evaluates to a pointer,
1385
1396
// so if the type of the location is a pointer,
1386
1397
// an &-operation is implied.
@@ -1873,7 +1884,8 @@ func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.P
1873
1884
1874
1885
// Determine number of iterations.
1875
1886
var length Value
1876
- if arr , ok := deref (x .Type ()).Underlying ().(* types.Array ); ok {
1887
+ dt , _ := deptr (x .Type ())
1888
+ if arr , ok := dt .Underlying ().(* types.Array ); ok {
1877
1889
// For array or *array, the number of iterations is
1878
1890
// known statically thanks to the type. We avoid a
1879
1891
// data dependence upon x, permitting later dead-code
@@ -1882,6 +1894,7 @@ func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.P
1882
1894
// We still generate code for x, in case it has effects.
1883
1895
//
1884
1896
// TypeParams do not have constant length. Use underlying instead of core type.
1897
+ // TODO: check if needed.
1885
1898
length = intConst (arr .Len ())
1886
1899
} else {
1887
1900
// length = len(x).
0 commit comments