vrp.go 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. package vrp
  2. // TODO(dh) widening and narrowing have a lot of code in common. Make
  3. // it reusable.
  4. import (
  5. "fmt"
  6. "go/constant"
  7. "go/token"
  8. "go/types"
  9. "math/big"
  10. "sort"
  11. "strings"
  12. "honnef.co/go/tools/lint"
  13. "honnef.co/go/tools/ssa"
  14. )
  15. type Future interface {
  16. Constraint
  17. Futures() []ssa.Value
  18. Resolve()
  19. IsKnown() bool
  20. MarkUnresolved()
  21. MarkResolved()
  22. IsResolved() bool
  23. }
  24. type Range interface {
  25. Union(other Range) Range
  26. IsKnown() bool
  27. }
  28. type Constraint interface {
  29. Y() ssa.Value
  30. isConstraint()
  31. String() string
  32. Eval(*Graph) Range
  33. Operands() []ssa.Value
  34. }
  35. type aConstraint struct {
  36. y ssa.Value
  37. }
  38. func NewConstraint(y ssa.Value) aConstraint {
  39. return aConstraint{y}
  40. }
  41. func (aConstraint) isConstraint() {}
  42. func (c aConstraint) Y() ssa.Value { return c.y }
  43. type PhiConstraint struct {
  44. aConstraint
  45. Vars []ssa.Value
  46. }
  47. func NewPhiConstraint(vars []ssa.Value, y ssa.Value) Constraint {
  48. uniqm := map[ssa.Value]struct{}{}
  49. for _, v := range vars {
  50. uniqm[v] = struct{}{}
  51. }
  52. var uniq []ssa.Value
  53. for v := range uniqm {
  54. uniq = append(uniq, v)
  55. }
  56. return &PhiConstraint{
  57. aConstraint: NewConstraint(y),
  58. Vars: uniq,
  59. }
  60. }
  61. func (c *PhiConstraint) Operands() []ssa.Value {
  62. return c.Vars
  63. }
  64. func (c *PhiConstraint) Eval(g *Graph) Range {
  65. i := Range(nil)
  66. for _, v := range c.Vars {
  67. i = g.Range(v).Union(i)
  68. }
  69. return i
  70. }
  71. func (c *PhiConstraint) String() string {
  72. names := make([]string, len(c.Vars))
  73. for i, v := range c.Vars {
  74. names[i] = v.Name()
  75. }
  76. return fmt.Sprintf("%s = φ(%s)", c.Y().Name(), strings.Join(names, ", "))
  77. }
  78. func isSupportedType(typ types.Type) bool {
  79. switch typ := typ.Underlying().(type) {
  80. case *types.Basic:
  81. switch typ.Kind() {
  82. case types.String, types.UntypedString:
  83. return true
  84. default:
  85. if (typ.Info() & types.IsInteger) == 0 {
  86. return false
  87. }
  88. }
  89. case *types.Chan:
  90. return true
  91. case *types.Slice:
  92. return true
  93. default:
  94. return false
  95. }
  96. return true
  97. }
  98. func ConstantToZ(c constant.Value) Z {
  99. s := constant.ToInt(c).ExactString()
  100. n := &big.Int{}
  101. n.SetString(s, 10)
  102. return NewBigZ(n)
  103. }
  104. func sigmaInteger(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
  105. op := cond.Op
  106. if !ins.Branch {
  107. op = (invertToken(op))
  108. }
  109. switch op {
  110. case token.EQL, token.GTR, token.GEQ, token.LSS, token.LEQ:
  111. default:
  112. return nil
  113. }
  114. var a, b ssa.Value
  115. if (*ops[0]) == ins.X {
  116. a = *ops[0]
  117. b = *ops[1]
  118. } else {
  119. a = *ops[1]
  120. b = *ops[0]
  121. op = flipToken(op)
  122. }
  123. return NewIntIntersectionConstraint(a, b, op, g.ranges, ins)
  124. }
  125. func sigmaString(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
  126. op := cond.Op
  127. if !ins.Branch {
  128. op = (invertToken(op))
  129. }
  130. switch op {
  131. case token.EQL, token.GTR, token.GEQ, token.LSS, token.LEQ:
  132. default:
  133. return nil
  134. }
  135. if ((*ops[0]).Type().Underlying().(*types.Basic).Info() & types.IsString) == 0 {
  136. var a, b ssa.Value
  137. call, ok := (*ops[0]).(*ssa.Call)
  138. if ok && call.Common().Args[0] == ins.X {
  139. a = *ops[0]
  140. b = *ops[1]
  141. } else {
  142. a = *ops[1]
  143. b = *ops[0]
  144. op = flipToken(op)
  145. }
  146. return NewStringIntersectionConstraint(a, b, op, g.ranges, ins)
  147. }
  148. var a, b ssa.Value
  149. if (*ops[0]) == ins.X {
  150. a = *ops[0]
  151. b = *ops[1]
  152. } else {
  153. a = *ops[1]
  154. b = *ops[0]
  155. op = flipToken(op)
  156. }
  157. return NewStringIntersectionConstraint(a, b, op, g.ranges, ins)
  158. }
  159. func sigmaSlice(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
  160. // TODO(dh) sigmaSlice and sigmaString are a lot alike. Can they
  161. // be merged?
  162. //
  163. // XXX support futures
  164. op := cond.Op
  165. if !ins.Branch {
  166. op = (invertToken(op))
  167. }
  168. k, ok := (*ops[1]).(*ssa.Const)
  169. // XXX investigate in what cases this wouldn't be a Const
  170. //
  171. // XXX what if left and right are swapped?
  172. if !ok {
  173. return nil
  174. }
  175. call, ok := (*ops[0]).(*ssa.Call)
  176. if !ok {
  177. return nil
  178. }
  179. builtin, ok := call.Common().Value.(*ssa.Builtin)
  180. if !ok {
  181. return nil
  182. }
  183. if builtin.Name() != "len" {
  184. return nil
  185. }
  186. callops := call.Operands(nil)
  187. v := ConstantToZ(k.Value)
  188. c := NewSliceIntersectionConstraint(*callops[1], IntInterval{}, ins).(*SliceIntersectionConstraint)
  189. switch op {
  190. case token.EQL:
  191. c.I = NewIntInterval(v, v)
  192. case token.GTR, token.GEQ:
  193. off := int64(0)
  194. if cond.Op == token.GTR {
  195. off = 1
  196. }
  197. c.I = NewIntInterval(
  198. v.Add(NewZ(off)),
  199. PInfinity,
  200. )
  201. case token.LSS, token.LEQ:
  202. off := int64(0)
  203. if cond.Op == token.LSS {
  204. off = -1
  205. }
  206. c.I = NewIntInterval(
  207. NInfinity,
  208. v.Add(NewZ(off)),
  209. )
  210. default:
  211. return nil
  212. }
  213. return c
  214. }
  215. func BuildGraph(f *ssa.Function) *Graph {
  216. g := &Graph{
  217. Vertices: map[interface{}]*Vertex{},
  218. ranges: Ranges{},
  219. }
  220. var cs []Constraint
  221. ops := make([]*ssa.Value, 16)
  222. seen := map[ssa.Value]bool{}
  223. for _, block := range f.Blocks {
  224. for _, ins := range block.Instrs {
  225. ops = ins.Operands(ops[:0])
  226. for _, op := range ops {
  227. if c, ok := (*op).(*ssa.Const); ok {
  228. if seen[c] {
  229. continue
  230. }
  231. seen[c] = true
  232. if c.Value == nil {
  233. switch c.Type().Underlying().(type) {
  234. case *types.Slice:
  235. cs = append(cs, NewSliceIntervalConstraint(NewIntInterval(NewZ(0), NewZ(0)), c))
  236. }
  237. continue
  238. }
  239. switch c.Value.Kind() {
  240. case constant.Int:
  241. v := ConstantToZ(c.Value)
  242. cs = append(cs, NewIntIntervalConstraint(NewIntInterval(v, v), c))
  243. case constant.String:
  244. s := constant.StringVal(c.Value)
  245. n := NewZ(int64(len(s)))
  246. cs = append(cs, NewStringIntervalConstraint(NewIntInterval(n, n), c))
  247. }
  248. }
  249. }
  250. }
  251. }
  252. for _, block := range f.Blocks {
  253. for _, ins := range block.Instrs {
  254. switch ins := ins.(type) {
  255. case *ssa.Convert:
  256. switch v := ins.Type().Underlying().(type) {
  257. case *types.Basic:
  258. if (v.Info() & types.IsInteger) == 0 {
  259. continue
  260. }
  261. cs = append(cs, NewIntConversionConstraint(ins.X, ins))
  262. }
  263. case *ssa.Call:
  264. if static := ins.Common().StaticCallee(); static != nil {
  265. if fn, ok := static.Object().(*types.Func); ok {
  266. switch lint.FuncName(fn) {
  267. case "bytes.Index", "bytes.IndexAny", "bytes.IndexByte",
  268. "bytes.IndexFunc", "bytes.IndexRune", "bytes.LastIndex",
  269. "bytes.LastIndexAny", "bytes.LastIndexByte", "bytes.LastIndexFunc",
  270. "strings.Index", "strings.IndexAny", "strings.IndexByte",
  271. "strings.IndexFunc", "strings.IndexRune", "strings.LastIndex",
  272. "strings.LastIndexAny", "strings.LastIndexByte", "strings.LastIndexFunc":
  273. // TODO(dh): instead of limiting by +∞,
  274. // limit by the upper bound of the passed
  275. // string
  276. cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(-1), PInfinity), ins))
  277. case "bytes.Title", "bytes.ToLower", "bytes.ToTitle", "bytes.ToUpper",
  278. "strings.Title", "strings.ToLower", "strings.ToTitle", "strings.ToUpper":
  279. cs = append(cs, NewCopyConstraint(ins.Common().Args[0], ins))
  280. case "bytes.ToLowerSpecial", "bytes.ToTitleSpecial", "bytes.ToUpperSpecial",
  281. "strings.ToLowerSpecial", "strings.ToTitleSpecial", "strings.ToUpperSpecial":
  282. cs = append(cs, NewCopyConstraint(ins.Common().Args[1], ins))
  283. case "bytes.Compare", "strings.Compare":
  284. cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(-1), NewZ(1)), ins))
  285. case "bytes.Count", "strings.Count":
  286. // TODO(dh): instead of limiting by +∞,
  287. // limit by the upper bound of the passed
  288. // string.
  289. cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(0), PInfinity), ins))
  290. case "bytes.Map", "bytes.TrimFunc", "bytes.TrimLeft", "bytes.TrimLeftFunc",
  291. "bytes.TrimRight", "bytes.TrimRightFunc", "bytes.TrimSpace",
  292. "strings.Map", "strings.TrimFunc", "strings.TrimLeft", "strings.TrimLeftFunc",
  293. "strings.TrimRight", "strings.TrimRightFunc", "strings.TrimSpace":
  294. // TODO(dh): lower = 0, upper = upper of passed string
  295. case "bytes.TrimPrefix", "bytes.TrimSuffix",
  296. "strings.TrimPrefix", "strings.TrimSuffix":
  297. // TODO(dh) range between "unmodified" and len(cutset) removed
  298. case "(*bytes.Buffer).Cap", "(*bytes.Buffer).Len", "(*bytes.Reader).Len", "(*bytes.Reader).Size":
  299. cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(0), PInfinity), ins))
  300. }
  301. }
  302. }
  303. builtin, ok := ins.Common().Value.(*ssa.Builtin)
  304. ops := ins.Operands(nil)
  305. if !ok {
  306. continue
  307. }
  308. switch builtin.Name() {
  309. case "len":
  310. switch op1 := (*ops[1]).Type().Underlying().(type) {
  311. case *types.Basic:
  312. if op1.Kind() == types.String || op1.Kind() == types.UntypedString {
  313. cs = append(cs, NewStringLengthConstraint(*ops[1], ins))
  314. }
  315. case *types.Slice:
  316. cs = append(cs, NewSliceLengthConstraint(*ops[1], ins))
  317. }
  318. case "append":
  319. cs = append(cs, NewSliceAppendConstraint(ins.Common().Args[0], ins.Common().Args[1], ins))
  320. }
  321. case *ssa.BinOp:
  322. ops := ins.Operands(nil)
  323. basic, ok := (*ops[0]).Type().Underlying().(*types.Basic)
  324. if !ok {
  325. continue
  326. }
  327. switch basic.Kind() {
  328. case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
  329. types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64, types.UntypedInt:
  330. fns := map[token.Token]func(ssa.Value, ssa.Value, ssa.Value) Constraint{
  331. token.ADD: NewIntAddConstraint,
  332. token.SUB: NewIntSubConstraint,
  333. token.MUL: NewIntMulConstraint,
  334. // XXX support QUO, REM, SHL, SHR
  335. }
  336. fn, ok := fns[ins.Op]
  337. if ok {
  338. cs = append(cs, fn(*ops[0], *ops[1], ins))
  339. }
  340. case types.String, types.UntypedString:
  341. if ins.Op == token.ADD {
  342. cs = append(cs, NewStringConcatConstraint(*ops[0], *ops[1], ins))
  343. }
  344. }
  345. case *ssa.Slice:
  346. typ := ins.X.Type().Underlying()
  347. switch typ := typ.(type) {
  348. case *types.Basic:
  349. cs = append(cs, NewStringSliceConstraint(ins.X, ins.Low, ins.High, ins))
  350. case *types.Slice:
  351. cs = append(cs, NewSliceSliceConstraint(ins.X, ins.Low, ins.High, ins))
  352. case *types.Array:
  353. cs = append(cs, NewArraySliceConstraint(ins.X, ins.Low, ins.High, ins))
  354. case *types.Pointer:
  355. if _, ok := typ.Elem().(*types.Array); !ok {
  356. continue
  357. }
  358. cs = append(cs, NewArraySliceConstraint(ins.X, ins.Low, ins.High, ins))
  359. }
  360. case *ssa.Phi:
  361. if !isSupportedType(ins.Type()) {
  362. continue
  363. }
  364. ops := ins.Operands(nil)
  365. dops := make([]ssa.Value, len(ops))
  366. for i, op := range ops {
  367. dops[i] = *op
  368. }
  369. cs = append(cs, NewPhiConstraint(dops, ins))
  370. case *ssa.Sigma:
  371. pred := ins.Block().Preds[0]
  372. instrs := pred.Instrs
  373. cond, ok := instrs[len(instrs)-1].(*ssa.If).Cond.(*ssa.BinOp)
  374. ops := cond.Operands(nil)
  375. if !ok {
  376. continue
  377. }
  378. switch typ := ins.Type().Underlying().(type) {
  379. case *types.Basic:
  380. var c Constraint
  381. switch typ.Kind() {
  382. case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
  383. types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64, types.UntypedInt:
  384. c = sigmaInteger(g, ins, cond, ops)
  385. case types.String, types.UntypedString:
  386. c = sigmaString(g, ins, cond, ops)
  387. }
  388. if c != nil {
  389. cs = append(cs, c)
  390. }
  391. case *types.Slice:
  392. c := sigmaSlice(g, ins, cond, ops)
  393. if c != nil {
  394. cs = append(cs, c)
  395. }
  396. default:
  397. //log.Printf("unsupported sigma type %T", typ) // XXX
  398. }
  399. case *ssa.MakeChan:
  400. cs = append(cs, NewMakeChannelConstraint(ins.Size, ins))
  401. case *ssa.MakeSlice:
  402. cs = append(cs, NewMakeSliceConstraint(ins.Len, ins))
  403. case *ssa.ChangeType:
  404. switch ins.X.Type().Underlying().(type) {
  405. case *types.Chan:
  406. cs = append(cs, NewChannelChangeTypeConstraint(ins.X, ins))
  407. }
  408. }
  409. }
  410. }
  411. for _, c := range cs {
  412. if c == nil {
  413. panic("nil constraint")
  414. }
  415. // If V is used in constraint C, then we create an edge V->C
  416. for _, op := range c.Operands() {
  417. g.AddEdge(op, c, false)
  418. }
  419. if c, ok := c.(Future); ok {
  420. for _, op := range c.Futures() {
  421. g.AddEdge(op, c, true)
  422. }
  423. }
  424. // If constraint C defines variable V, then we create an edge
  425. // C->V
  426. g.AddEdge(c, c.Y(), false)
  427. }
  428. g.FindSCCs()
  429. g.sccEdges = make([][]Edge, len(g.SCCs))
  430. g.futures = make([][]Future, len(g.SCCs))
  431. for _, e := range g.Edges {
  432. g.sccEdges[e.From.SCC] = append(g.sccEdges[e.From.SCC], e)
  433. if !e.control {
  434. continue
  435. }
  436. if c, ok := e.To.Value.(Future); ok {
  437. g.futures[e.From.SCC] = append(g.futures[e.From.SCC], c)
  438. }
  439. }
  440. return g
  441. }
  442. func (g *Graph) Solve() Ranges {
  443. var consts []Z
  444. off := NewZ(1)
  445. for _, n := range g.Vertices {
  446. if c, ok := n.Value.(*ssa.Const); ok {
  447. basic, ok := c.Type().Underlying().(*types.Basic)
  448. if !ok {
  449. continue
  450. }
  451. if (basic.Info() & types.IsInteger) != 0 {
  452. z := ConstantToZ(c.Value)
  453. consts = append(consts, z)
  454. consts = append(consts, z.Add(off))
  455. consts = append(consts, z.Sub(off))
  456. }
  457. }
  458. }
  459. sort.Sort(Zs(consts))
  460. for scc, vertices := range g.SCCs {
  461. n := 0
  462. n = len(vertices)
  463. if n == 1 {
  464. g.resolveFutures(scc)
  465. v := vertices[0]
  466. if v, ok := v.Value.(ssa.Value); ok {
  467. switch typ := v.Type().Underlying().(type) {
  468. case *types.Basic:
  469. switch typ.Kind() {
  470. case types.String, types.UntypedString:
  471. if !g.Range(v).(StringInterval).IsKnown() {
  472. g.SetRange(v, StringInterval{NewIntInterval(NewZ(0), PInfinity)})
  473. }
  474. default:
  475. if !g.Range(v).(IntInterval).IsKnown() {
  476. g.SetRange(v, InfinityFor(v))
  477. }
  478. }
  479. case *types.Chan:
  480. if !g.Range(v).(ChannelInterval).IsKnown() {
  481. g.SetRange(v, ChannelInterval{NewIntInterval(NewZ(0), PInfinity)})
  482. }
  483. case *types.Slice:
  484. if !g.Range(v).(SliceInterval).IsKnown() {
  485. g.SetRange(v, SliceInterval{NewIntInterval(NewZ(0), PInfinity)})
  486. }
  487. }
  488. }
  489. if c, ok := v.Value.(Constraint); ok {
  490. g.SetRange(c.Y(), c.Eval(g))
  491. }
  492. } else {
  493. uses := g.uses(scc)
  494. entries := g.entries(scc)
  495. for len(entries) > 0 {
  496. v := entries[len(entries)-1]
  497. entries = entries[:len(entries)-1]
  498. for _, use := range uses[v] {
  499. if g.widen(use, consts) {
  500. entries = append(entries, use.Y())
  501. }
  502. }
  503. }
  504. g.resolveFutures(scc)
  505. // XXX this seems to be necessary, but shouldn't be.
  506. // removing it leads to nil pointer derefs; investigate
  507. // where we're not setting values correctly.
  508. for _, n := range vertices {
  509. if v, ok := n.Value.(ssa.Value); ok {
  510. i, ok := g.Range(v).(IntInterval)
  511. if !ok {
  512. continue
  513. }
  514. if !i.IsKnown() {
  515. g.SetRange(v, InfinityFor(v))
  516. }
  517. }
  518. }
  519. actives := g.actives(scc)
  520. for len(actives) > 0 {
  521. v := actives[len(actives)-1]
  522. actives = actives[:len(actives)-1]
  523. for _, use := range uses[v] {
  524. if g.narrow(use) {
  525. actives = append(actives, use.Y())
  526. }
  527. }
  528. }
  529. }
  530. // propagate scc
  531. for _, edge := range g.sccEdges[scc] {
  532. if edge.control {
  533. continue
  534. }
  535. if edge.From.SCC == edge.To.SCC {
  536. continue
  537. }
  538. if c, ok := edge.To.Value.(Constraint); ok {
  539. g.SetRange(c.Y(), c.Eval(g))
  540. }
  541. if c, ok := edge.To.Value.(Future); ok {
  542. if !c.IsKnown() {
  543. c.MarkUnresolved()
  544. }
  545. }
  546. }
  547. }
  548. for v, r := range g.ranges {
  549. i, ok := r.(IntInterval)
  550. if !ok {
  551. continue
  552. }
  553. if (v.Type().Underlying().(*types.Basic).Info() & types.IsUnsigned) == 0 {
  554. if i.Upper != PInfinity {
  555. s := &types.StdSizes{
  556. // XXX is it okay to assume the largest word size, or do we
  557. // need to be platform specific?
  558. WordSize: 8,
  559. MaxAlign: 1,
  560. }
  561. bits := (s.Sizeof(v.Type()) * 8) - 1
  562. n := big.NewInt(1)
  563. n = n.Lsh(n, uint(bits))
  564. upper, lower := &big.Int{}, &big.Int{}
  565. upper.Sub(n, big.NewInt(1))
  566. lower.Neg(n)
  567. if i.Upper.Cmp(NewBigZ(upper)) == 1 {
  568. i = NewIntInterval(NInfinity, PInfinity)
  569. } else if i.Lower.Cmp(NewBigZ(lower)) == -1 {
  570. i = NewIntInterval(NInfinity, PInfinity)
  571. }
  572. }
  573. }
  574. g.ranges[v] = i
  575. }
  576. return g.ranges
  577. }
  578. func VertexString(v *Vertex) string {
  579. switch v := v.Value.(type) {
  580. case Constraint:
  581. return v.String()
  582. case ssa.Value:
  583. return v.Name()
  584. case nil:
  585. return "BUG: nil vertex value"
  586. default:
  587. panic(fmt.Sprintf("unexpected type %T", v))
  588. }
  589. }
  590. type Vertex struct {
  591. Value interface{} // one of Constraint or ssa.Value
  592. SCC int
  593. index int
  594. lowlink int
  595. stack bool
  596. Succs []Edge
  597. }
  598. type Ranges map[ssa.Value]Range
  599. func (r Ranges) Get(x ssa.Value) Range {
  600. if x == nil {
  601. return nil
  602. }
  603. i, ok := r[x]
  604. if !ok {
  605. switch x := x.Type().Underlying().(type) {
  606. case *types.Basic:
  607. switch x.Kind() {
  608. case types.String, types.UntypedString:
  609. return StringInterval{}
  610. default:
  611. return IntInterval{}
  612. }
  613. case *types.Chan:
  614. return ChannelInterval{}
  615. case *types.Slice:
  616. return SliceInterval{}
  617. }
  618. }
  619. return i
  620. }
  621. type Graph struct {
  622. Vertices map[interface{}]*Vertex
  623. Edges []Edge
  624. SCCs [][]*Vertex
  625. ranges Ranges
  626. // map SCCs to futures
  627. futures [][]Future
  628. // map SCCs to edges
  629. sccEdges [][]Edge
  630. }
  631. func (g Graph) Graphviz() string {
  632. var lines []string
  633. lines = append(lines, "digraph{")
  634. ids := map[interface{}]int{}
  635. i := 1
  636. for _, v := range g.Vertices {
  637. ids[v] = i
  638. shape := "box"
  639. if _, ok := v.Value.(ssa.Value); ok {
  640. shape = "oval"
  641. }
  642. lines = append(lines, fmt.Sprintf(`n%d [shape="%s", label=%q, colorscheme=spectral11, style="filled", fillcolor="%d"]`,
  643. i, shape, VertexString(v), (v.SCC%11)+1))
  644. i++
  645. }
  646. for _, e := range g.Edges {
  647. style := "solid"
  648. if e.control {
  649. style = "dashed"
  650. }
  651. lines = append(lines, fmt.Sprintf(`n%d -> n%d [style="%s"]`, ids[e.From], ids[e.To], style))
  652. }
  653. lines = append(lines, "}")
  654. return strings.Join(lines, "\n")
  655. }
  656. func (g *Graph) SetRange(x ssa.Value, r Range) {
  657. g.ranges[x] = r
  658. }
  659. func (g *Graph) Range(x ssa.Value) Range {
  660. return g.ranges.Get(x)
  661. }
  662. func (g *Graph) widen(c Constraint, consts []Z) bool {
  663. setRange := func(i Range) {
  664. g.SetRange(c.Y(), i)
  665. }
  666. widenIntInterval := func(oi, ni IntInterval) (IntInterval, bool) {
  667. if !ni.IsKnown() {
  668. return oi, false
  669. }
  670. nlc := NInfinity
  671. nuc := PInfinity
  672. // Don't get stuck widening for an absurd amount of time due
  673. // to an excess number of constants, as may be present in
  674. // table-based scanners.
  675. if len(consts) < 1000 {
  676. for _, co := range consts {
  677. if co.Cmp(ni.Lower) <= 0 {
  678. nlc = co
  679. break
  680. }
  681. }
  682. for _, co := range consts {
  683. if co.Cmp(ni.Upper) >= 0 {
  684. nuc = co
  685. break
  686. }
  687. }
  688. }
  689. if !oi.IsKnown() {
  690. return ni, true
  691. }
  692. if ni.Lower.Cmp(oi.Lower) == -1 && ni.Upper.Cmp(oi.Upper) == 1 {
  693. return NewIntInterval(nlc, nuc), true
  694. }
  695. if ni.Lower.Cmp(oi.Lower) == -1 {
  696. return NewIntInterval(nlc, oi.Upper), true
  697. }
  698. if ni.Upper.Cmp(oi.Upper) == 1 {
  699. return NewIntInterval(oi.Lower, nuc), true
  700. }
  701. return oi, false
  702. }
  703. switch oi := g.Range(c.Y()).(type) {
  704. case IntInterval:
  705. ni := c.Eval(g).(IntInterval)
  706. si, changed := widenIntInterval(oi, ni)
  707. if changed {
  708. setRange(si)
  709. return true
  710. }
  711. return false
  712. case StringInterval:
  713. ni := c.Eval(g).(StringInterval)
  714. si, changed := widenIntInterval(oi.Length, ni.Length)
  715. if changed {
  716. setRange(StringInterval{si})
  717. return true
  718. }
  719. return false
  720. case SliceInterval:
  721. ni := c.Eval(g).(SliceInterval)
  722. si, changed := widenIntInterval(oi.Length, ni.Length)
  723. if changed {
  724. setRange(SliceInterval{si})
  725. return true
  726. }
  727. return false
  728. default:
  729. return false
  730. }
  731. }
  732. func (g *Graph) narrow(c Constraint) bool {
  733. narrowIntInterval := func(oi, ni IntInterval) (IntInterval, bool) {
  734. oLower := oi.Lower
  735. oUpper := oi.Upper
  736. nLower := ni.Lower
  737. nUpper := ni.Upper
  738. if oLower == NInfinity && nLower != NInfinity {
  739. return NewIntInterval(nLower, oUpper), true
  740. }
  741. if oUpper == PInfinity && nUpper != PInfinity {
  742. return NewIntInterval(oLower, nUpper), true
  743. }
  744. if oLower.Cmp(nLower) == 1 {
  745. return NewIntInterval(nLower, oUpper), true
  746. }
  747. if oUpper.Cmp(nUpper) == -1 {
  748. return NewIntInterval(oLower, nUpper), true
  749. }
  750. return oi, false
  751. }
  752. switch oi := g.Range(c.Y()).(type) {
  753. case IntInterval:
  754. ni := c.Eval(g).(IntInterval)
  755. si, changed := narrowIntInterval(oi, ni)
  756. if changed {
  757. g.SetRange(c.Y(), si)
  758. return true
  759. }
  760. return false
  761. case StringInterval:
  762. ni := c.Eval(g).(StringInterval)
  763. si, changed := narrowIntInterval(oi.Length, ni.Length)
  764. if changed {
  765. g.SetRange(c.Y(), StringInterval{si})
  766. return true
  767. }
  768. return false
  769. case SliceInterval:
  770. ni := c.Eval(g).(SliceInterval)
  771. si, changed := narrowIntInterval(oi.Length, ni.Length)
  772. if changed {
  773. g.SetRange(c.Y(), SliceInterval{si})
  774. return true
  775. }
  776. return false
  777. default:
  778. return false
  779. }
  780. }
  781. func (g *Graph) resolveFutures(scc int) {
  782. for _, c := range g.futures[scc] {
  783. c.Resolve()
  784. }
  785. }
  786. func (g *Graph) entries(scc int) []ssa.Value {
  787. var entries []ssa.Value
  788. for _, n := range g.Vertices {
  789. if n.SCC != scc {
  790. continue
  791. }
  792. if v, ok := n.Value.(ssa.Value); ok {
  793. // XXX avoid quadratic runtime
  794. //
  795. // XXX I cannot think of any code where the future and its
  796. // variables aren't in the same SCC, in which case this
  797. // code isn't very useful (the variables won't be resolved
  798. // yet). Before we have a cross-SCC example, however, we
  799. // can't really verify that this code is working
  800. // correctly, or indeed doing anything useful.
  801. for _, on := range g.Vertices {
  802. if c, ok := on.Value.(Future); ok {
  803. if c.Y() == v {
  804. if !c.IsResolved() {
  805. g.SetRange(c.Y(), c.Eval(g))
  806. c.MarkResolved()
  807. }
  808. break
  809. }
  810. }
  811. }
  812. if g.Range(v).IsKnown() {
  813. entries = append(entries, v)
  814. }
  815. }
  816. }
  817. return entries
  818. }
  819. func (g *Graph) uses(scc int) map[ssa.Value][]Constraint {
  820. m := map[ssa.Value][]Constraint{}
  821. for _, e := range g.sccEdges[scc] {
  822. if e.control {
  823. continue
  824. }
  825. if v, ok := e.From.Value.(ssa.Value); ok {
  826. c := e.To.Value.(Constraint)
  827. sink := c.Y()
  828. if g.Vertices[sink].SCC == scc {
  829. m[v] = append(m[v], c)
  830. }
  831. }
  832. }
  833. return m
  834. }
  835. func (g *Graph) actives(scc int) []ssa.Value {
  836. var actives []ssa.Value
  837. for _, n := range g.Vertices {
  838. if n.SCC != scc {
  839. continue
  840. }
  841. if v, ok := n.Value.(ssa.Value); ok {
  842. if _, ok := v.(*ssa.Const); !ok {
  843. actives = append(actives, v)
  844. }
  845. }
  846. }
  847. return actives
  848. }
  849. func (g *Graph) AddEdge(from, to interface{}, ctrl bool) {
  850. vf, ok := g.Vertices[from]
  851. if !ok {
  852. vf = &Vertex{Value: from}
  853. g.Vertices[from] = vf
  854. }
  855. vt, ok := g.Vertices[to]
  856. if !ok {
  857. vt = &Vertex{Value: to}
  858. g.Vertices[to] = vt
  859. }
  860. e := Edge{From: vf, To: vt, control: ctrl}
  861. g.Edges = append(g.Edges, e)
  862. vf.Succs = append(vf.Succs, e)
  863. }
  864. type Edge struct {
  865. From, To *Vertex
  866. control bool
  867. }
  868. func (e Edge) String() string {
  869. return fmt.Sprintf("%s -> %s", VertexString(e.From), VertexString(e.To))
  870. }
  871. func (g *Graph) FindSCCs() {
  872. // use Tarjan to find the SCCs
  873. index := 1
  874. var s []*Vertex
  875. scc := 0
  876. var strongconnect func(v *Vertex)
  877. strongconnect = func(v *Vertex) {
  878. // set the depth index for v to the smallest unused index
  879. v.index = index
  880. v.lowlink = index
  881. index++
  882. s = append(s, v)
  883. v.stack = true
  884. for _, e := range v.Succs {
  885. w := e.To
  886. if w.index == 0 {
  887. // successor w has not yet been visited; recurse on it
  888. strongconnect(w)
  889. if w.lowlink < v.lowlink {
  890. v.lowlink = w.lowlink
  891. }
  892. } else if w.stack {
  893. // successor w is in stack s and hence in the current scc
  894. if w.index < v.lowlink {
  895. v.lowlink = w.index
  896. }
  897. }
  898. }
  899. if v.lowlink == v.index {
  900. for {
  901. w := s[len(s)-1]
  902. s = s[:len(s)-1]
  903. w.stack = false
  904. w.SCC = scc
  905. if w == v {
  906. break
  907. }
  908. }
  909. scc++
  910. }
  911. }
  912. for _, v := range g.Vertices {
  913. if v.index == 0 {
  914. strongconnect(v)
  915. }
  916. }
  917. g.SCCs = make([][]*Vertex, scc)
  918. for _, n := range g.Vertices {
  919. n.SCC = scc - n.SCC - 1
  920. g.SCCs[n.SCC] = append(g.SCCs[n.SCC], n)
  921. }
  922. }
  923. func invertToken(tok token.Token) token.Token {
  924. switch tok {
  925. case token.LSS:
  926. return token.GEQ
  927. case token.GTR:
  928. return token.LEQ
  929. case token.EQL:
  930. return token.NEQ
  931. case token.NEQ:
  932. return token.EQL
  933. case token.GEQ:
  934. return token.LSS
  935. case token.LEQ:
  936. return token.GTR
  937. default:
  938. panic(fmt.Sprintf("unsupported token %s", tok))
  939. }
  940. }
  941. func flipToken(tok token.Token) token.Token {
  942. switch tok {
  943. case token.LSS:
  944. return token.GTR
  945. case token.GTR:
  946. return token.LSS
  947. case token.EQL:
  948. return token.EQL
  949. case token.NEQ:
  950. return token.NEQ
  951. case token.GEQ:
  952. return token.LEQ
  953. case token.LEQ:
  954. return token.GEQ
  955. default:
  956. panic(fmt.Sprintf("unsupported token %s", tok))
  957. }
  958. }
  959. type CopyConstraint struct {
  960. aConstraint
  961. X ssa.Value
  962. }
  963. func (c *CopyConstraint) String() string {
  964. return fmt.Sprintf("%s = copy(%s)", c.Y().Name(), c.X.Name())
  965. }
  966. func (c *CopyConstraint) Eval(g *Graph) Range {
  967. return g.Range(c.X)
  968. }
  969. func (c *CopyConstraint) Operands() []ssa.Value {
  970. return []ssa.Value{c.X}
  971. }
  972. func NewCopyConstraint(x, y ssa.Value) Constraint {
  973. return &CopyConstraint{
  974. aConstraint: aConstraint{
  975. y: y,
  976. },
  977. X: x,
  978. }
  979. }