lift handling of ->immutable into dup_token()

We need to make sure that any struct string with more than one token
refering to it will have ->immutable set; that's what de1fa7e60 ("Make
macro expanded string immutable") tried to achieve.  Unfortunately, it
was not enough - constructing an example where an unexpanded argument gets
several copies is very easy (see the testcase in this commit).

A better place for dealing with that is dup_token() - that's guaranteed
to catch all such tokens and with sane code generation (== with compiler
made certain that *streampos can't be altered by stores to alloc->pos)
it's quite cheap; we already have alloc->pos in registers and checking
if the lower 6 bits happen to be 001000 or 001001 (TOKEN_STRING and
TOKEN_WIDE_STRING resp.) doesn't take much.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2 files changed
tree: 56d71c06fb4c7cba0f335d85bc051c7b7f787727
  1. compat/
  2. Documentation/
  3. gvpr/
  4. validation/
  5. .gitignore
  6. .readthedocs.yaml
  7. allocate.c
  8. allocate.h
  9. ast-inspect.c
  10. ast-inspect.h
  11. ast-model.c
  12. ast-model.h
  13. ast-view.c
  14. ast-view.h
  15. bitmap.h
  16. bits.h
  17. builtin.c
  18. builtin.h
  19. c2xml.c
  20. cgcc
  21. cgcc.1
  22. char.c
  23. char.h
  24. compat-bsd.c
  25. compat-cygwin.c
  26. compat-linux.c
  27. compat-mingw.c
  28. compat-solaris.c
  29. compat.h
  30. compile-i386.c
  31. compile.c
  32. compile.h
  33. cse.c
  34. cse.h
  35. ctags.c
  36. dissect.c
  37. dissect.h
  38. dominate.c
  39. dominate.h
  40. evaluate.c
  41. evaluate.h
  42. example.c
  43. expand.c
  44. expand.h
  45. expression.c
  46. expression.h
  47. FAQ
  48. flow.c
  49. flow.h
  50. flowgraph.c
  51. flowgraph.h
  52. gcc-attr-list.h
  53. gdbhelpers
  54. graph.c
  55. ident-list.h
  56. inline.c
  57. ir.c
  58. ir.h
  59. lib.c
  60. lib.h
  61. LICENSE
  62. linearize.c
  63. linearize.h
  64. liveness.c
  65. liveness.h
  66. machine.h
  67. Makefile
  68. memops.c
  69. obfuscate.c
  70. opcode.c
  71. opcode.def
  72. opcode.h
  73. optimize.c
  74. optimize.h
  75. options.c
  76. options.h
  77. parse.c
  78. parse.dtd
  79. parse.h
  80. pre-process.c
  81. predefine.c
  82. ptrlist.c
  83. ptrlist.h
  84. ptrmap.c
  85. ptrmap.h
  86. README
  87. scheck.c
  88. scope.c
  89. scope.h
  90. semind.1
  91. semind.c
  92. show-parse.c
  93. simplify.c
  94. simplify.h
  95. sort.c
  96. sparse-llvm-dis
  97. sparse-llvm.c
  98. sparse.1
  99. sparse.c
  100. sparsec
  101. sparsei
  102. ssa.c
  103. ssa.h
  104. stats.c
  105. storage.c
  106. storage.h
  107. symbol.c
  108. symbol.h
  109. target-alpha.c
  110. target-arm.c
  111. target-arm64.c
  112. target-bfin.c
  113. target-default.c
  114. target-h8300.c
  115. target-m68k.c
  116. target-microblaze.c
  117. target-mips.c
  118. target-nds32.c
  119. target-nios2.c
  120. target-openrisc.c
  121. target-ppc.c
  122. target-riscv.c
  123. target-s390.c
  124. target-sh.c
  125. target-sparc.c
  126. target-x86.c
  127. target-xtensa.c
  128. target.c
  129. target.h
  130. test-dissect.c
  131. test-inspect.c
  132. test-lexing.c
  133. test-linearize.c
  134. test-parsing.c
  135. test-show-type.c
  136. test-sort.c
  137. test-unssa.c
  138. token.h
  139. tokenize.c
  140. unssa.c
  141. utils.c
  142. utils.h
  143. version.c