Current implementation of isDereferenceableAndAlignedPointer is messy. It tries to handle sized/non-sized types, looking through casts/relocations and inherent value dereferenceability properties in a single recursive function. Recent addition of alignment handling and context-sensitive non-null analysis made it even worse. This patch is an attempt to clean it up.
Inherent value dereferenceability properties are now handled in Value class:
- Value::isDereferenceablePointer
- Value::getDereferenceableBytes
The code which tracks dereferencability over a chain of values remains in ValueTracking. isDereferenceableAndAlignedPointer is no longer recursive. Instead it uses helper functions to strip all the casts/compute a base pointer and offset.
Overall structure of this code is as follows:
- Try to determine if a value is dereferenceable without dealing with type sizes. Strip type safe transformations only: address space casts, global aliases, GC relocations. If the resulting pointer is fully dereferenceable we are done. It will handle derferencability of opaque types.
- If the accessed type is sized try to decompose the value to a base pointer and an offset. Check if the accessed value lies within dereferenceable portion of the base pointer.