semstrictfuncs.nim 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2022 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## New "strict funcs" checking. Much simpler and hopefully easier to teach than
  10. ## the old but more advanced algorithm that can/could be found in `varpartitions.nim`.
  11. import ast, typeallowed, renderer
  12. from aliasanalysis import PathKinds0, PathKinds1
  13. from trees import getMagic
  14. proc isDangerousLocation*(n: PNode; owner: PSym): bool =
  15. var n = n
  16. var hasDeref = false
  17. while true:
  18. case n.kind
  19. of nkDerefExpr, nkHiddenDeref:
  20. if n[0].typ.kind != tyVar:
  21. hasDeref = true
  22. n = n[0]
  23. of PathKinds0 - {nkDerefExpr, nkHiddenDeref}:
  24. n = n[0]
  25. of PathKinds1:
  26. n = n[1]
  27. of nkCallKinds:
  28. if n.len > 1:
  29. if (n.typ != nil and classifyViewType(n.typ) != noView) or getMagic(n) == mSlice:
  30. # borrow from first parameter:
  31. n = n[1]
  32. else:
  33. break
  34. else:
  35. break
  36. else:
  37. break
  38. if n.kind == nkSym:
  39. # dangerous if contains a pointer deref or if it doesn't belong to us:
  40. result = hasDeref or n.sym.owner != owner
  41. when false:
  42. # store to something that belongs to a `var` parameter is fine:
  43. let s = n.sym
  44. if s.kind == skParam:
  45. # dangerous unless a `var T` parameter:
  46. result = s.typ.kind != tyVar
  47. else:
  48. # dangerous if contains a pointer deref or if it doesn't belong to us:
  49. result = hasDeref or s.owner != owner
  50. else:
  51. # dangerous if it contains a pointer deref
  52. result = hasDeref