func visitIndexAddr(inst *ssa.IndexAddr, fr *frame) { elem := inst array := inst.X index := inst.Index _, isArray := deref(array.Type()).Underlying().(*types.Array) _, isSlice := deref(array.Type()).Underlying().(*types.Slice) if isArray || isSlice { switch vd, kind := fr.get(array); kind { case Array: fmt.Fprintf(os.Stderr, " %s = &%s(=%s)[%d] of type %s\n", cyan(reg(elem)), array.Name(), vd.String(), index, elem.Type().String()) if fr.env.arrays[vd][index] == nil { // First use vdelem := utils.NewDef(elem) fr.env.arrays[vd][index] = vdelem fmt.Fprintf(os.Stderr, " ^ accessed for the first time: use %s as elem definition\n", elem.Name()) } else if fr.env.arrays[vd][index].Var != elem { // Previously defined fmt.Fprintf(os.Stderr, " ^ elem %s previously defined as %s\n", elem.Name(), reg(fr.env.arrays[vd][index].Var)) } // else Accessed before (and unchanged) fr.locals[elem] = fr.env.arrays[vd][index] case LocalArray: fmt.Fprintf(os.Stderr, " %s = &%s(=%s)[%d] (local) of type %s\n", cyan(reg(elem)), array.Name(), vd.String(), index, elem.Type().String()) if fr.arrays[vd][index] == nil { // First use vdElem := utils.NewDef(elem) fr.arrays[vd][index] = vdElem fmt.Fprintf(os.Stderr, " ^ accessed for the first time: use %s as elem definition\n", elem.Name()) } else if fr.arrays[vd][index].Var != elem { // Previously defined fmt.Fprintf(os.Stderr, " ^ elem %s previously defined as %s\n", elem.Name(), reg(fr.arrays[vd][index].Var)) } // else Accessed before (and unchanged) fr.locals[elem] = fr.arrays[vd][index] case Nothing, Untracked: // Nothing: Very likely external struct. // Untracked: likely branches of return values (e.g. returning nil) fmt.Fprintf(os.Stderr, " %s = &%s(=%s)[%d] (external) of type %s\n", cyan(reg(elem)), inst.X.Name(), vd.String(), index, elem.Type().String()) vd := utils.NewDef(array) // New external array fr.locals[array] = vd fr.env.arrays[vd] = make(Elems) vdElem := utils.NewDef(elem) // New external elem fr.env.arrays[vd][index] = vdElem fr.locals[elem] = vdElem fmt.Fprintf(os.Stderr, " ^ accessed for the first time: use %s as elem definition of type %s\n", elem.Name(), inst.Type().(*types.Pointer).Elem().Underlying().String()) default: panic(fmt.Sprintf("IndexAddr: Cannot access non-array %s", reg(array))) } } else { panic(fmt.Sprintf("IndexAddr: Cannot access field - %s not an array", reg(array))) } }