The SymbolMetadata handing was slightly flawed.
Given the following example:
void strcat_models_dst_length_even_if_src_dies(char *src) { char dst[8] = "1234"; strcat(dst, src); clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} }
A metadata symbol was assigned to the cstring length map, representing the new length of the dst:
'dst -> meta{src} + 4' where meta{src} represents the cstring length of the region of src.
Unfortunately, this information was immediately removed from the model, since the src become dead after the evaluation of calling strcat.
This results in the removal of all symbolic expressions (eg metadata symbols) that refers to the dead src memory region.
As of now, MetadataSymbols are used only by the CStringChecker, so this fix is tightly coupled to fixing the resulting issues of that checker.
There was already a FIXME in the test suite for this - which is now resolved.
There was a lengthy discussion on the mailing list how to resolve this issue.
In that mailing, @NoQ proposed these steps, which I have implemented in this patch:
- Remove statement, location context, block count from SymbolMetadata's identity. Let it solely depend on the region.
- Get rid of the metadata-in-use set. From now on SymbolMetadata, like SymbolRegionValue, is live whenever its region is live.
- When strlen(R) is used for the first time on a region R, produce $meta<size_t R> as the answer, but *do not store* it in the string length map. We don't need to change the state because the state didn't in fact change. On subsequent strlen(R) calls we'll simply return the same symbol (because the map will remain empty), until the string is changed.
- If the string is mutated, record its length as usual. But if the string is invalidated (or the new length is completely unknown), do not remove the length from the state; instead, set it to SymbolConjured. Only remove it from the map when the region dies.
- Keep string length symbols alive as long as they're in the map.
I think the comments should be updated as well: remove "in use" and refer to the aliveness of the memregion.