}
ok := 0
-OpSwitch:
switch n.Op {
// until typecheck is complete, do nothing.
default:
if n.Type == nil && n.Val().Ctype() == CTSTR {
n.Type = types.Idealstring
}
- break OpSwitch
case ONONAME:
ok |= Erv
- break OpSwitch
case ONAME:
if n.Name.Decldepth == 0 {
}
if n.Etype != 0 {
ok |= Ecall
- break OpSwitch
+ break
}
if top&Easgn == 0 {
}
ok |= Erv
- break OpSwitch
case OPACK:
yyerror("use of package %v without selector", n.Sym)
checkwidth(l.Type)
}
n.Left = nil
- break OpSwitch
+ break
}
if !t.IsPtr() {
return n
}
- break OpSwitch
+ break
}
ok |= Erv
n.Type = t.Elem()
- break OpSwitch
// arithmetic exprs
case OASOP,
// the outer context gives the type
n.Type = l.Type
- break OpSwitch
+ break
}
// ideal mixed with non-ideal
}
n.Type = t
- break OpSwitch
case OCOM, OMINUS, ONOT, OPLUS:
ok |= Erv
}
n.Type = t
- break OpSwitch
// exprs
case OADDR:
return n
}
n.Type = types.NewPtr(t)
- break OpSwitch
case OCOMPLIT:
ok |= Erv
if n.Type == nil {
return n
}
- break OpSwitch
case OXDOT, ODOT:
if n.Op == OXDOT {
n.Xoffset = 0
n.SetClass(PFUNC)
ok = Erv
- break OpSwitch
+ break
}
if t.IsPtr() && !t.Elem().IsInterface() {
ok |= Erv
}
- break OpSwitch
-
case ODOTTYPE:
ok |= Erv
n.Left = typecheck(n.Left, Erv)
}
}
- break OpSwitch
-
case OINDEX:
ok |= Erv
n.Left = typecheck(n.Left, Erv)
n.Op = OINDEXMAP
}
- break OpSwitch
-
case ORECV:
ok |= Etop | Erv
n.Left = typecheck(n.Left, Erv)
}
n.Type = t.Elem()
- break OpSwitch
case OSEND:
ok |= Etop
n.Etype = 0
n.Type = nil
- break OpSwitch
case OSLICE, OSLICE3:
ok |= Erv
n.Type = nil
return n
}
- break OpSwitch
// call and call like
case OCALL:
typecheckaste(OCALL, n.Left, n.Isddd(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
ok |= Etop
if t.NumResults() == 0 {
- break OpSwitch
+ break
}
ok |= Erv
if t.NumResults() == 1 {
n.Op = OGETG
}
- break OpSwitch
+ break
}
// multiple return
if top&(Efnstruct|Etop) == 0 {
yyerror("multiple-value %v() in single-value context", l)
- break OpSwitch
+ break
}
n.Type = l.Type.Results()
- break OpSwitch
-
case OALIGNOF, OOFFSETOF, OSIZEOF:
ok |= Erv
if !onearg(n, "%v", n.Op) {
r.Orig = n
n = &r
- break OpSwitch
-
case OCAP, OLEN:
ok |= Erv
if !onearg(n, "%v", n.Op) {
}
n.Type = types.Types[TINT]
- break OpSwitch
case OREAL, OIMAG:
ok |= Erv
Fatalf("unexpected Etype: %v\n", et)
}
n.Type = types.Types[et]
- break OpSwitch
case OCOMPLEX:
ok |= Erv
}
n.Type = t
- break OpSwitch
case OCLOSE:
if !onearg(n, "%v", n.Op) {
}
ok |= Etop
- break OpSwitch
case ODELETE:
args := n.List
}
args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
- break OpSwitch
case OAPPEND:
ok |= Erv
if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
- break OpSwitch
+ break
}
args.SetSecond(assignconv(args.Second(), t.Orig, "append"))
- break OpSwitch
+ break
}
if funarg != nil {
}
}
- break OpSwitch
-
case OCOPY:
ok |= Etop | Erv
args := n.List
// copy([]byte, string)
if n.Left.Type.IsSlice() && n.Right.Type.IsString() {
if eqtype(n.Left.Type.Elem(), types.Bytetype) {
- break OpSwitch
+ break
}
yyerror("arguments to copy have different element types: %L and string", n.Left.Type)
n.Type = nil
return n
}
- break OpSwitch
-
case OCONV:
ok |= Erv
saveorignode(n)
}
}
- break OpSwitch
-
case OMAKE:
ok |= Erv
args := n.List.Slice()
}
n.Type = t
- break OpSwitch
case ONEW:
ok |= Erv
n.Left = l
n.Type = types.NewPtr(t)
- break OpSwitch
case OPRINT, OPRINTN:
ok |= Etop
}
}
- break OpSwitch
-
case OPANIC:
ok |= Etop
if !onearg(n, "panic") {
n.Type = nil
return n
}
- break OpSwitch
case ORECOVER:
ok |= Erv | Etop
}
n.Type = types.Types[TINTER]
- break OpSwitch
case OCLOSURE:
ok |= Erv
if n.Type == nil {
return n
}
- break OpSwitch
case OITAB:
ok |= Erv
Fatalf("OITAB of %v", t)
}
n.Type = types.NewPtr(types.Types[TUINTPTR])
- break OpSwitch
case OIDATA:
// Whoever creates the OIDATA node must know a priori the concrete type at that moment,
// usually by just having checked the OITAB.
Fatalf("cannot typecheck interface data %v", n)
- break OpSwitch
case OSPTR:
ok |= Erv
} else {
n.Type = types.NewPtr(t.Elem())
}
- break OpSwitch
case OCLOSUREVAR:
ok |= Erv
- break OpSwitch
case OCFUNC:
ok |= Erv
n.Left = typecheck(n.Left, Erv)
n.Type = types.Types[TUINTPTR]
- break OpSwitch
case OCONVNOP:
ok |= Erv
n.Left = typecheck(n.Left, Erv)
- break OpSwitch
// statements
case OAS:
if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
n.Left.Name.Defn = n
}
- break OpSwitch
case OAS2:
ok |= Etop
typecheckas2(n)
- break OpSwitch
case OBREAK,
OCONTINUE,
OVARKILL,
OVARLIVE:
ok |= Etop
- break OpSwitch
case OLABEL:
ok |= Etop
n.Op = OEMPTY
n.Left = nil
}
- break OpSwitch
case ODEFER:
ok |= Etop
if !n.Left.Diag() {
checkdefergo(n)
}
- break OpSwitch
case OPROC:
ok |= Etop
n.Left = typecheck(n.Left, Etop|Erv)
checkdefergo(n)
- break OpSwitch
case OFOR, OFORUNTIL:
ok |= Etop
n.Right = typecheck(n.Right, Etop)
typecheckslice(n.Nbody.Slice(), Etop)
decldepth--
- break OpSwitch
case OIF:
ok |= Etop
}
typecheckslice(n.Nbody.Slice(), Etop)
typecheckslice(n.Rlist.Slice(), Etop)
- break OpSwitch
case ORETURN:
ok |= Etop
}
if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
- break OpSwitch
+ break
}
typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
- break OpSwitch
case ORETJMP:
ok |= Etop
- break OpSwitch
case OSELECT:
ok |= Etop
typecheckselect(n)
- break OpSwitch
case OSWITCH:
ok |= Etop
typecheckswitch(n)
- break OpSwitch
case ORANGE:
ok |= Etop
typecheckrange(n)
- break OpSwitch
case OTYPESW:
yyerror("use of .(type) outside type switch")
ok |= Etop
typecheckslice(n.List.Slice(), Erv)
typecheckslice(n.Nbody.Slice(), Etop)
- break OpSwitch
case ODCLFUNC:
ok |= Etop
typecheckfunc(n)
- break OpSwitch
case ODCLCONST:
ok |= Etop
n.Left = typecheck(n.Left, Erv)
- break OpSwitch
case ODCLTYPE:
ok |= Etop
// could silently propagate go:notinheap).
yyerror("type %v must be go:notinheap", n.Left.Type)
}
- break OpSwitch
}
t := n.Type