Skip to content

Compile “length(string/array) = 0” as “pointer(string/array) = nil”.

Rika requested to merge runewalsh/source:length=0 into main

This resolves #39549. Disclaimer: I don’t understand what’s going on and just tried randomly.

COM-based widestring must be the only counterexample so far, and it was already special-cased in TransformLengthZero because of the different length format.

Code irresponsible to the point of maliciousness that, say, manually writes 0 to the header is broken even without this MR: for example, reference_counted_string = '' is compiled simply as pointer(reference_counted_string) = nil, which would wrongly return false with such an injected Len = 0, and shows that the assumption that pointer(s) = nil iff length(s) = 0 has been with us all along.

Additionally, this handles:

  • Length <> 0 as not (Length = 0),
  • Length > 0 as Length <> 0,
  • Length <= 0 as Length = 0,
  • Length >= 0 as true,
  • Length < 0 as false. (These two could warn.)

By my rough estimate with length\s*\(.*\)\s*(=|<>|>|<|>=|<=)\s*0 accounting for its tons of false positives, there are around 100–150 occurences in RTL and 300–500 in packages, and many of them are Length > 0.

Merge request reports