github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/typecheck/expr.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package typecheck 6 7 import ( 8 "fmt" 9 "go/constant" 10 "go/token" 11 "strings" 12 13 "github.com/go-asm/go/types/errors" 14 15 "github.com/go-asm/go/cmd/compile/base" 16 "github.com/go-asm/go/cmd/compile/ir" 17 "github.com/go-asm/go/cmd/compile/types" 18 "github.com/go-asm/go/cmd/src" 19 ) 20 21 func tcShift(n, l, r ir.Node) (ir.Node, ir.Node, *types.Type) { 22 if l.Type() == nil || r.Type() == nil { 23 return l, r, nil 24 } 25 26 r = DefaultLit(r, types.Types[types.TUINT]) 27 t := r.Type() 28 if !t.IsInteger() { 29 base.Errorf("invalid operation: %v (shift count type %v, must be integer)", n, r.Type()) 30 return l, r, nil 31 } 32 t = l.Type() 33 if t != nil && t.Kind() != types.TIDEAL && !t.IsInteger() { 34 base.Errorf("invalid operation: %v (shift of type %v)", n, t) 35 return l, r, nil 36 } 37 38 // no DefaultLit for left 39 // the outer context gives the type 40 t = l.Type() 41 if (l.Type() == types.UntypedFloat || l.Type() == types.UntypedComplex) && r.Op() == ir.OLITERAL { 42 t = types.UntypedInt 43 } 44 return l, r, t 45 } 46 47 // tcArith typechecks operands of a binary arithmetic expression. 48 // The result of tcArith MUST be assigned back to original operands, 49 // t is the type of the expression, and should be set by the caller. e.g: 50 // 51 // n.X, n.Y, t = tcArith(n, op, n.X, n.Y) 52 // n.SetType(t) 53 func tcArith(n ir.Node, op ir.Op, l, r ir.Node) (ir.Node, ir.Node, *types.Type) { 54 l, r = defaultlit2(l, r, false) 55 if l.Type() == nil || r.Type() == nil { 56 return l, r, nil 57 } 58 t := l.Type() 59 if t.Kind() == types.TIDEAL { 60 t = r.Type() 61 } 62 aop := ir.OXXX 63 if n.Op().IsCmp() && t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) { 64 // comparison is okay as long as one side is 65 // assignable to the other. convert so they have 66 // the same type. 67 // 68 // the only conversion that isn't a no-op is concrete == interface. 69 // in that case, check comparability of the concrete type. 70 // The conversion allocates, so only do it if the concrete type is huge. 71 converted := false 72 if r.Type().Kind() != types.TBLANK { 73 aop, _ = assignOp(l.Type(), r.Type()) 74 if aop != ir.OXXX { 75 if r.Type().IsInterface() && !l.Type().IsInterface() && !types.IsComparable(l.Type()) { 76 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type())) 77 return l, r, nil 78 } 79 80 types.CalcSize(l.Type()) 81 if r.Type().IsInterface() == l.Type().IsInterface() || l.Type().Size() >= 1<<16 { 82 l = ir.NewConvExpr(base.Pos, aop, r.Type(), l) 83 l.SetTypecheck(1) 84 } 85 86 t = r.Type() 87 converted = true 88 } 89 } 90 91 if !converted && l.Type().Kind() != types.TBLANK { 92 aop, _ = assignOp(r.Type(), l.Type()) 93 if aop != ir.OXXX { 94 if l.Type().IsInterface() && !r.Type().IsInterface() && !types.IsComparable(r.Type()) { 95 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type())) 96 return l, r, nil 97 } 98 99 types.CalcSize(r.Type()) 100 if r.Type().IsInterface() == l.Type().IsInterface() || r.Type().Size() >= 1<<16 { 101 r = ir.NewConvExpr(base.Pos, aop, l.Type(), r) 102 r.SetTypecheck(1) 103 } 104 105 t = l.Type() 106 } 107 } 108 } 109 110 if t.Kind() != types.TIDEAL && !types.Identical(l.Type(), r.Type()) { 111 l, r = defaultlit2(l, r, true) 112 if l.Type() == nil || r.Type() == nil { 113 return l, r, nil 114 } 115 if l.Type().IsInterface() == r.Type().IsInterface() || aop == 0 { 116 base.Errorf("invalid operation: %v (mismatched types %v and %v)", n, l.Type(), r.Type()) 117 return l, r, nil 118 } 119 } 120 121 if t.Kind() == types.TIDEAL { 122 t = mixUntyped(l.Type(), r.Type()) 123 } 124 if dt := defaultType(t); !okfor[op][dt.Kind()] { 125 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(t)) 126 return l, r, nil 127 } 128 129 // okfor allows any array == array, map == map, func == func. 130 // restrict to slice/map/func == nil and nil == slice/map/func. 131 if l.Type().IsArray() && !types.IsComparable(l.Type()) { 132 base.Errorf("invalid operation: %v (%v cannot be compared)", n, l.Type()) 133 return l, r, nil 134 } 135 136 if l.Type().IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) { 137 base.Errorf("invalid operation: %v (slice can only be compared to nil)", n) 138 return l, r, nil 139 } 140 141 if l.Type().IsMap() && !ir.IsNil(l) && !ir.IsNil(r) { 142 base.Errorf("invalid operation: %v (map can only be compared to nil)", n) 143 return l, r, nil 144 } 145 146 if l.Type().Kind() == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) { 147 base.Errorf("invalid operation: %v (func can only be compared to nil)", n) 148 return l, r, nil 149 } 150 151 if l.Type().IsStruct() { 152 if f := types.IncomparableField(l.Type()); f != nil { 153 base.Errorf("invalid operation: %v (struct containing %v cannot be compared)", n, f.Type) 154 return l, r, nil 155 } 156 } 157 158 return l, r, t 159 } 160 161 // The result of tcCompLit MUST be assigned back to n, e.g. 162 // 163 // n.Left = tcCompLit(n.Left) 164 func tcCompLit(n *ir.CompLitExpr) (res ir.Node) { 165 if base.EnableTrace && base.Flag.LowerT { 166 defer tracePrint("tcCompLit", n)(&res) 167 } 168 169 lno := base.Pos 170 defer func() { 171 base.Pos = lno 172 }() 173 174 ir.SetPos(n) 175 176 t := n.Type() 177 base.AssertfAt(t != nil, n.Pos(), "missing type in composite literal") 178 179 switch t.Kind() { 180 default: 181 base.Errorf("invalid composite literal type %v", t) 182 n.SetType(nil) 183 184 case types.TARRAY: 185 typecheckarraylit(t.Elem(), t.NumElem(), n.List, "array literal") 186 n.SetOp(ir.OARRAYLIT) 187 188 case types.TSLICE: 189 length := typecheckarraylit(t.Elem(), -1, n.List, "slice literal") 190 n.SetOp(ir.OSLICELIT) 191 n.Len = length 192 193 case types.TMAP: 194 for i3, l := range n.List { 195 ir.SetPos(l) 196 if l.Op() != ir.OKEY { 197 n.List[i3] = Expr(l) 198 base.Errorf("missing key in map literal") 199 continue 200 } 201 l := l.(*ir.KeyExpr) 202 203 r := l.Key 204 r = Expr(r) 205 l.Key = AssignConv(r, t.Key(), "map key") 206 207 r = l.Value 208 r = Expr(r) 209 l.Value = AssignConv(r, t.Elem(), "map value") 210 } 211 212 n.SetOp(ir.OMAPLIT) 213 214 case types.TSTRUCT: 215 // Need valid field offsets for Xoffset below. 216 types.CalcSize(t) 217 218 errored := false 219 if len(n.List) != 0 && nokeys(n.List) { 220 // simple list of variables 221 ls := n.List 222 for i, n1 := range ls { 223 ir.SetPos(n1) 224 n1 = Expr(n1) 225 ls[i] = n1 226 if i >= t.NumFields() { 227 if !errored { 228 base.Errorf("too many values in %v", n) 229 errored = true 230 } 231 continue 232 } 233 234 f := t.Field(i) 235 s := f.Sym 236 237 // Do the test for assigning to unexported fields. 238 // But if this is an instantiated function, then 239 // the function has already been typechecked. In 240 // that case, don't do the test, since it can fail 241 // for the closure structs created in 242 // walkClosure(), because the instantiated 243 // function is compiled as if in the source 244 // package of the generic function. 245 if !(ir.CurFunc != nil && strings.Contains(ir.CurFunc.Nname.Sym().Name, "[")) { 246 if s != nil && !types.IsExported(s.Name) && s.Pkg != types.LocalPkg { 247 base.Errorf("implicit assignment of unexported field '%s' in %v literal", s.Name, t) 248 } 249 } 250 // No pushtype allowed here. Must name fields for that. 251 n1 = AssignConv(n1, f.Type, "field value") 252 ls[i] = ir.NewStructKeyExpr(base.Pos, f, n1) 253 } 254 if len(ls) < t.NumFields() { 255 base.Errorf("too few values in %v", n) 256 } 257 } else { 258 hash := make(map[string]bool) 259 260 // keyed list 261 ls := n.List 262 for i, n := range ls { 263 ir.SetPos(n) 264 265 sk, ok := n.(*ir.StructKeyExpr) 266 if !ok { 267 kv, ok := n.(*ir.KeyExpr) 268 if !ok { 269 if !errored { 270 base.Errorf("mixture of field:value and value initializers") 271 errored = true 272 } 273 ls[i] = Expr(n) 274 continue 275 } 276 277 sk = tcStructLitKey(t, kv) 278 if sk == nil { 279 continue 280 } 281 282 fielddup(sk.Sym().Name, hash) 283 } 284 285 // No pushtype allowed here. Tried and rejected. 286 sk.Value = Expr(sk.Value) 287 sk.Value = AssignConv(sk.Value, sk.Field.Type, "field value") 288 ls[i] = sk 289 } 290 } 291 292 n.SetOp(ir.OSTRUCTLIT) 293 } 294 295 return n 296 } 297 298 // tcStructLitKey typechecks an OKEY node that appeared within a 299 // struct literal. 300 func tcStructLitKey(typ *types.Type, kv *ir.KeyExpr) *ir.StructKeyExpr { 301 key := kv.Key 302 303 sym := key.Sym() 304 305 // An OXDOT uses the Sym field to hold 306 // the field to the right of the dot, 307 // so s will be non-nil, but an OXDOT 308 // is never a valid struct literal key. 309 if sym == nil || sym.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || sym.IsBlank() { 310 base.Errorf("invalid field name %v in struct initializer", key) 311 return nil 312 } 313 314 if f := Lookdot1(nil, sym, typ, typ.Fields(), 0); f != nil { 315 return ir.NewStructKeyExpr(kv.Pos(), f, kv.Value) 316 } 317 318 if ci := Lookdot1(nil, sym, typ, typ.Fields(), 2); ci != nil { // Case-insensitive lookup. 319 if visible(ci.Sym) { 320 base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", sym, typ, ci.Sym) 321 } else if nonexported(sym) && sym.Name == ci.Sym.Name { // Ensure exactness before the suggestion. 322 base.Errorf("cannot refer to unexported field '%v' in struct literal of type %v", sym, typ) 323 } else { 324 base.Errorf("unknown field '%v' in struct literal of type %v", sym, typ) 325 } 326 return nil 327 } 328 329 var f *types.Field 330 p, _ := dotpath(sym, typ, &f, true) 331 if p == nil || f.IsMethod() { 332 base.Errorf("unknown field '%v' in struct literal of type %v", sym, typ) 333 return nil 334 } 335 336 // dotpath returns the parent embedded types in reverse order. 337 var ep []string 338 for ei := len(p) - 1; ei >= 0; ei-- { 339 ep = append(ep, p[ei].field.Sym.Name) 340 } 341 ep = append(ep, sym.Name) 342 base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), typ) 343 return nil 344 } 345 346 // tcConv typechecks an OCONV node. 347 func tcConv(n *ir.ConvExpr) ir.Node { 348 types.CheckSize(n.Type()) // ensure width is calculated for backend 349 n.X = Expr(n.X) 350 n.X = convlit1(n.X, n.Type(), true, nil) 351 t := n.X.Type() 352 if t == nil || n.Type() == nil { 353 n.SetType(nil) 354 return n 355 } 356 op, why := convertOp(n.X.Op() == ir.OLITERAL, t, n.Type()) 357 if op == ir.OXXX { 358 // Due to //go:nointerface, we may be stricter than types2 here (#63333). 359 base.ErrorfAt(n.Pos(), errors.InvalidConversion, "cannot convert %L to type %v%s", n.X, n.Type(), why) 360 n.SetType(nil) 361 return n 362 } 363 364 n.SetOp(op) 365 switch n.Op() { 366 case ir.OCONVNOP: 367 if t.Kind() == n.Type().Kind() { 368 switch t.Kind() { 369 case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128: 370 // Floating point casts imply rounding and 371 // so the conversion must be kept. 372 n.SetOp(ir.OCONV) 373 } 374 } 375 376 // do not convert to []byte literal. See CL 125796. 377 // generated code and compiler memory footprint is better without it. 378 case ir.OSTR2BYTES: 379 // ok 380 381 case ir.OSTR2RUNES: 382 if n.X.Op() == ir.OLITERAL { 383 return stringtoruneslit(n) 384 } 385 386 case ir.OBYTES2STR: 387 if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] { 388 // If t is a slice of a user-defined byte type B (not uint8 389 // or byte), then add an extra CONVNOP from []B to []byte, so 390 // that the call to slicebytetostring() added in walk will 391 // typecheck correctly. 392 n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X) 393 n.X.SetTypecheck(1) 394 } 395 396 case ir.ORUNES2STR: 397 if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] { 398 // If t is a slice of a user-defined rune type B (not uint32 399 // or rune), then add an extra CONVNOP from []B to []rune, so 400 // that the call to slicerunetostring() added in walk will 401 // typecheck correctly. 402 n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X) 403 n.X.SetTypecheck(1) 404 } 405 406 } 407 return n 408 } 409 410 // DotField returns a field selector expression that selects the 411 // index'th field of the given expression, which must be of struct or 412 // pointer-to-struct type. 413 func DotField(pos src.XPos, x ir.Node, index int) *ir.SelectorExpr { 414 op, typ := ir.ODOT, x.Type() 415 if typ.IsPtr() { 416 op, typ = ir.ODOTPTR, typ.Elem() 417 } 418 if !typ.IsStruct() { 419 base.FatalfAt(pos, "DotField of non-struct: %L", x) 420 } 421 422 // TODO(mdempsky): This is the backend's responsibility. 423 types.CalcSize(typ) 424 425 field := typ.Field(index) 426 return dot(pos, field.Type, op, x, field) 427 } 428 429 func dot(pos src.XPos, typ *types.Type, op ir.Op, x ir.Node, selection *types.Field) *ir.SelectorExpr { 430 n := ir.NewSelectorExpr(pos, op, x, selection.Sym) 431 n.Selection = selection 432 n.SetType(typ) 433 n.SetTypecheck(1) 434 return n 435 } 436 437 // XDotMethod returns an expression representing the field selection 438 // x.sym. If any implicit field selection are necessary, those are 439 // inserted too. 440 func XDotField(pos src.XPos, x ir.Node, sym *types.Sym) *ir.SelectorExpr { 441 n := Expr(ir.NewSelectorExpr(pos, ir.OXDOT, x, sym)).(*ir.SelectorExpr) 442 if n.Op() != ir.ODOT && n.Op() != ir.ODOTPTR { 443 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n) 444 } 445 return n 446 } 447 448 // XDotMethod returns an expression representing the method value 449 // x.sym (i.e., x is a value, not a type). If any implicit field 450 // selection are necessary, those are inserted too. 451 // 452 // If callee is true, the result is an ODOTMETH/ODOTINTER, otherwise 453 // an OMETHVALUE. 454 func XDotMethod(pos src.XPos, x ir.Node, sym *types.Sym, callee bool) *ir.SelectorExpr { 455 n := ir.NewSelectorExpr(pos, ir.OXDOT, x, sym) 456 if callee { 457 n = Callee(n).(*ir.SelectorExpr) 458 if n.Op() != ir.ODOTMETH && n.Op() != ir.ODOTINTER { 459 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n) 460 } 461 } else { 462 n = Expr(n).(*ir.SelectorExpr) 463 if n.Op() != ir.OMETHVALUE { 464 base.FatalfAt(pos, "unexpected result op: %v (%v)", n.Op(), n) 465 } 466 } 467 return n 468 } 469 470 // tcDot typechecks an OXDOT or ODOT node. 471 func tcDot(n *ir.SelectorExpr, top int) ir.Node { 472 if n.Op() == ir.OXDOT { 473 n = AddImplicitDots(n) 474 n.SetOp(ir.ODOT) 475 if n.X == nil { 476 n.SetType(nil) 477 return n 478 } 479 } 480 481 n.X = Expr(n.X) 482 n.X = DefaultLit(n.X, nil) 483 484 t := n.X.Type() 485 if t == nil { 486 base.UpdateErrorDot(ir.Line(n), fmt.Sprint(n.X), fmt.Sprint(n)) 487 n.SetType(nil) 488 return n 489 } 490 491 if n.X.Op() == ir.OTYPE { 492 base.FatalfAt(n.Pos(), "use NewMethodExpr to construct OMETHEXPR") 493 } 494 495 if t.IsPtr() && !t.Elem().IsInterface() { 496 t = t.Elem() 497 if t == nil { 498 n.SetType(nil) 499 return n 500 } 501 n.SetOp(ir.ODOTPTR) 502 types.CheckSize(t) 503 } 504 505 if n.Sel.IsBlank() { 506 base.Errorf("cannot refer to blank field or method") 507 n.SetType(nil) 508 return n 509 } 510 511 if Lookdot(n, t, 0) == nil { 512 // Legitimate field or method lookup failed, try to explain the error 513 switch { 514 case t.IsEmptyInterface(): 515 base.Errorf("%v undefined (type %v is interface with no methods)", n, n.X.Type()) 516 517 case t.IsPtr() && t.Elem().IsInterface(): 518 // Pointer to interface is almost always a mistake. 519 base.Errorf("%v undefined (type %v is pointer to interface, not interface)", n, n.X.Type()) 520 521 case Lookdot(n, t, 1) != nil: 522 // Field or method matches by name, but it is not exported. 523 base.Errorf("%v undefined (cannot refer to unexported field or method %v)", n, n.Sel) 524 525 default: 526 if mt := Lookdot(n, t, 2); mt != nil && visible(mt.Sym) { // Case-insensitive lookup. 527 base.Errorf("%v undefined (type %v has no field or method %v, but does have %v)", n, n.X.Type(), n.Sel, mt.Sym) 528 } else { 529 base.Errorf("%v undefined (type %v has no field or method %v)", n, n.X.Type(), n.Sel) 530 } 531 } 532 n.SetType(nil) 533 return n 534 } 535 536 if (n.Op() == ir.ODOTINTER || n.Op() == ir.ODOTMETH) && top&ctxCallee == 0 { 537 n.SetOp(ir.OMETHVALUE) 538 n.SetType(NewMethodType(n.Type(), nil)) 539 } 540 return n 541 } 542 543 // tcDotType typechecks an ODOTTYPE node. 544 func tcDotType(n *ir.TypeAssertExpr) ir.Node { 545 n.X = Expr(n.X) 546 n.X = DefaultLit(n.X, nil) 547 l := n.X 548 t := l.Type() 549 if t == nil { 550 n.SetType(nil) 551 return n 552 } 553 if !t.IsInterface() { 554 base.Errorf("invalid type assertion: %v (non-interface type %v on left)", n, t) 555 n.SetType(nil) 556 return n 557 } 558 559 base.AssertfAt(n.Type() != nil, n.Pos(), "missing type: %v", n) 560 561 if n.Type() != nil && !n.Type().IsInterface() { 562 why := ImplementsExplain(n.Type(), t) 563 if why != "" { 564 base.Fatalf("impossible type assertion:\n\t%s", why) 565 n.SetType(nil) 566 return n 567 } 568 } 569 return n 570 } 571 572 // tcITab typechecks an OITAB node. 573 func tcITab(n *ir.UnaryExpr) ir.Node { 574 n.X = Expr(n.X) 575 t := n.X.Type() 576 if t == nil { 577 n.SetType(nil) 578 return n 579 } 580 if !t.IsInterface() { 581 base.Fatalf("OITAB of %v", t) 582 } 583 n.SetType(types.NewPtr(types.Types[types.TUINTPTR])) 584 return n 585 } 586 587 // tcIndex typechecks an OINDEX node. 588 func tcIndex(n *ir.IndexExpr) ir.Node { 589 n.X = Expr(n.X) 590 n.X = DefaultLit(n.X, nil) 591 n.X = implicitstar(n.X) 592 l := n.X 593 n.Index = Expr(n.Index) 594 r := n.Index 595 t := l.Type() 596 if t == nil || r.Type() == nil { 597 n.SetType(nil) 598 return n 599 } 600 switch t.Kind() { 601 default: 602 base.Errorf("invalid operation: %v (type %v does not support indexing)", n, t) 603 n.SetType(nil) 604 return n 605 606 case types.TSTRING, types.TARRAY, types.TSLICE: 607 n.Index = indexlit(n.Index) 608 if t.IsString() { 609 n.SetType(types.ByteType) 610 } else { 611 n.SetType(t.Elem()) 612 } 613 why := "string" 614 if t.IsArray() { 615 why = "array" 616 } else if t.IsSlice() { 617 why = "slice" 618 } 619 620 if n.Index.Type() != nil && !n.Index.Type().IsInteger() { 621 base.Errorf("non-integer %s index %v", why, n.Index) 622 return n 623 } 624 625 if !n.Bounded() && ir.IsConst(n.Index, constant.Int) { 626 x := n.Index.Val() 627 if constant.Sign(x) < 0 { 628 base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Index) 629 } else if t.IsArray() && constant.Compare(x, token.GEQ, constant.MakeInt64(t.NumElem())) { 630 base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Index, t.NumElem()) 631 } else if ir.IsConst(n.X, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(ir.StringVal(n.X))))) { 632 base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Index, len(ir.StringVal(n.X))) 633 } else if ir.ConstOverflow(x, types.Types[types.TINT]) { 634 base.Errorf("invalid %s index %v (index too large)", why, n.Index) 635 } 636 } 637 638 case types.TMAP: 639 n.Index = AssignConv(n.Index, t.Key(), "map index") 640 n.SetType(t.Elem()) 641 n.SetOp(ir.OINDEXMAP) 642 n.Assigned = false 643 } 644 return n 645 } 646 647 // tcLenCap typechecks an OLEN or OCAP node. 648 func tcLenCap(n *ir.UnaryExpr) ir.Node { 649 n.X = Expr(n.X) 650 n.X = DefaultLit(n.X, nil) 651 n.X = implicitstar(n.X) 652 l := n.X 653 t := l.Type() 654 if t == nil { 655 n.SetType(nil) 656 return n 657 } 658 659 var ok bool 660 if n.Op() == ir.OLEN { 661 ok = okforlen[t.Kind()] 662 } else { 663 ok = okforcap[t.Kind()] 664 } 665 if !ok { 666 base.Errorf("invalid argument %L for %v", l, n.Op()) 667 n.SetType(nil) 668 return n 669 } 670 671 n.SetType(types.Types[types.TINT]) 672 return n 673 } 674 675 // tcUnsafeData typechecks an OUNSAFESLICEDATA or OUNSAFESTRINGDATA node. 676 func tcUnsafeData(n *ir.UnaryExpr) ir.Node { 677 n.X = Expr(n.X) 678 n.X = DefaultLit(n.X, nil) 679 l := n.X 680 t := l.Type() 681 if t == nil { 682 n.SetType(nil) 683 return n 684 } 685 686 var kind types.Kind 687 if n.Op() == ir.OUNSAFESLICEDATA { 688 kind = types.TSLICE 689 } else { 690 /* kind is string */ 691 kind = types.TSTRING 692 } 693 694 if t.Kind() != kind { 695 base.Errorf("invalid argument %L for %v", l, n.Op()) 696 n.SetType(nil) 697 return n 698 } 699 700 if kind == types.TSTRING { 701 t = types.ByteType 702 } else { 703 t = t.Elem() 704 } 705 n.SetType(types.NewPtr(t)) 706 return n 707 } 708 709 // tcRecv typechecks an ORECV node. 710 func tcRecv(n *ir.UnaryExpr) ir.Node { 711 n.X = Expr(n.X) 712 n.X = DefaultLit(n.X, nil) 713 l := n.X 714 t := l.Type() 715 if t == nil { 716 n.SetType(nil) 717 return n 718 } 719 if !t.IsChan() { 720 base.Errorf("invalid operation: %v (receive from non-chan type %v)", n, t) 721 n.SetType(nil) 722 return n 723 } 724 725 if !t.ChanDir().CanRecv() { 726 base.Errorf("invalid operation: %v (receive from send-only type %v)", n, t) 727 n.SetType(nil) 728 return n 729 } 730 731 n.SetType(t.Elem()) 732 return n 733 } 734 735 // tcSPtr typechecks an OSPTR node. 736 func tcSPtr(n *ir.UnaryExpr) ir.Node { 737 n.X = Expr(n.X) 738 t := n.X.Type() 739 if t == nil { 740 n.SetType(nil) 741 return n 742 } 743 if !t.IsSlice() && !t.IsString() { 744 base.Fatalf("OSPTR of %v", t) 745 } 746 if t.IsString() { 747 n.SetType(types.NewPtr(types.Types[types.TUINT8])) 748 } else { 749 n.SetType(types.NewPtr(t.Elem())) 750 } 751 return n 752 } 753 754 // tcSlice typechecks an OSLICE or OSLICE3 node. 755 func tcSlice(n *ir.SliceExpr) ir.Node { 756 n.X = DefaultLit(Expr(n.X), nil) 757 n.Low = indexlit(Expr(n.Low)) 758 n.High = indexlit(Expr(n.High)) 759 n.Max = indexlit(Expr(n.Max)) 760 hasmax := n.Op().IsSlice3() 761 l := n.X 762 if l.Type() == nil { 763 n.SetType(nil) 764 return n 765 } 766 if l.Type().IsArray() { 767 if !ir.IsAddressable(n.X) { 768 base.Errorf("invalid operation %v (slice of unaddressable value)", n) 769 n.SetType(nil) 770 return n 771 } 772 773 addr := NodAddr(n.X) 774 addr.SetImplicit(true) 775 n.X = Expr(addr) 776 l = n.X 777 } 778 t := l.Type() 779 var tp *types.Type 780 if t.IsString() { 781 if hasmax { 782 base.Errorf("invalid operation %v (3-index slice of string)", n) 783 n.SetType(nil) 784 return n 785 } 786 n.SetType(t) 787 n.SetOp(ir.OSLICESTR) 788 } else if t.IsPtr() && t.Elem().IsArray() { 789 tp = t.Elem() 790 n.SetType(types.NewSlice(tp.Elem())) 791 types.CalcSize(n.Type()) 792 if hasmax { 793 n.SetOp(ir.OSLICE3ARR) 794 } else { 795 n.SetOp(ir.OSLICEARR) 796 } 797 } else if t.IsSlice() { 798 n.SetType(t) 799 } else { 800 base.Errorf("cannot slice %v (type %v)", l, t) 801 n.SetType(nil) 802 return n 803 } 804 805 if n.Low != nil && !checksliceindex(l, n.Low, tp) { 806 n.SetType(nil) 807 return n 808 } 809 if n.High != nil && !checksliceindex(l, n.High, tp) { 810 n.SetType(nil) 811 return n 812 } 813 if n.Max != nil && !checksliceindex(l, n.Max, tp) { 814 n.SetType(nil) 815 return n 816 } 817 if !checksliceconst(n.Low, n.High) || !checksliceconst(n.Low, n.Max) || !checksliceconst(n.High, n.Max) { 818 n.SetType(nil) 819 return n 820 } 821 return n 822 } 823 824 // tcSliceHeader typechecks an OSLICEHEADER node. 825 func tcSliceHeader(n *ir.SliceHeaderExpr) ir.Node { 826 // Errors here are Fatalf instead of Errorf because only the compiler 827 // can construct an OSLICEHEADER node. 828 // Components used in OSLICEHEADER that are supplied by parsed source code 829 // have already been typechecked in e.g. OMAKESLICE earlier. 830 t := n.Type() 831 if t == nil { 832 base.Fatalf("no type specified for OSLICEHEADER") 833 } 834 835 if !t.IsSlice() { 836 base.Fatalf("invalid type %v for OSLICEHEADER", n.Type()) 837 } 838 839 if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() { 840 base.Fatalf("need unsafe.Pointer for OSLICEHEADER") 841 } 842 843 n.Ptr = Expr(n.Ptr) 844 n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT]) 845 n.Cap = DefaultLit(Expr(n.Cap), types.Types[types.TINT]) 846 847 if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 { 848 base.Fatalf("len for OSLICEHEADER must be non-negative") 849 } 850 851 if ir.IsConst(n.Cap, constant.Int) && ir.Int64Val(n.Cap) < 0 { 852 base.Fatalf("cap for OSLICEHEADER must be non-negative") 853 } 854 855 if ir.IsConst(n.Len, constant.Int) && ir.IsConst(n.Cap, constant.Int) && constant.Compare(n.Len.Val(), token.GTR, n.Cap.Val()) { 856 base.Fatalf("len larger than cap for OSLICEHEADER") 857 } 858 859 return n 860 } 861 862 // tcStringHeader typechecks an OSTRINGHEADER node. 863 func tcStringHeader(n *ir.StringHeaderExpr) ir.Node { 864 t := n.Type() 865 if t == nil { 866 base.Fatalf("no type specified for OSTRINGHEADER") 867 } 868 869 if !t.IsString() { 870 base.Fatalf("invalid type %v for OSTRINGHEADER", n.Type()) 871 } 872 873 if n.Ptr == nil || n.Ptr.Type() == nil || !n.Ptr.Type().IsUnsafePtr() { 874 base.Fatalf("need unsafe.Pointer for OSTRINGHEADER") 875 } 876 877 n.Ptr = Expr(n.Ptr) 878 n.Len = DefaultLit(Expr(n.Len), types.Types[types.TINT]) 879 880 if ir.IsConst(n.Len, constant.Int) && ir.Int64Val(n.Len) < 0 { 881 base.Fatalf("len for OSTRINGHEADER must be non-negative") 882 } 883 884 return n 885 } 886 887 // tcStar typechecks an ODEREF node, which may be an expression or a type. 888 func tcStar(n *ir.StarExpr, top int) ir.Node { 889 n.X = typecheck(n.X, ctxExpr|ctxType) 890 l := n.X 891 t := l.Type() 892 if t == nil { 893 n.SetType(nil) 894 return n 895 } 896 897 // TODO(mdempsky): Remove (along with ctxType above) once I'm 898 // confident this code path isn't needed any more. 899 if l.Op() == ir.OTYPE { 900 base.Fatalf("unexpected type in deref expression: %v", l) 901 } 902 903 if !t.IsPtr() { 904 if top&(ctxExpr|ctxStmt) != 0 { 905 base.Errorf("invalid indirect of %L", n.X) 906 n.SetType(nil) 907 return n 908 } 909 base.Errorf("%v is not a type", l) 910 return n 911 } 912 913 n.SetType(t.Elem()) 914 return n 915 } 916 917 // tcUnaryArith typechecks a unary arithmetic expression. 918 func tcUnaryArith(n *ir.UnaryExpr) ir.Node { 919 n.X = Expr(n.X) 920 l := n.X 921 t := l.Type() 922 if t == nil { 923 n.SetType(nil) 924 return n 925 } 926 if !okfor[n.Op()][defaultType(t).Kind()] { 927 base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op(), typekind(t)) 928 n.SetType(nil) 929 return n 930 } 931 932 n.SetType(t) 933 return n 934 }