This is an archive of the discontinued LLVM Phabricator instance.

[CFG] [analyzer] NFC: Enumerate construction context layer kinds and re-use their code for ExprEngine keys.
ClosedPublic

Authored by NoQ on Jul 11 2018, 5:46 PM.

Details

Summary

This is a refactoring patch; no functional change intended.

ConstructionContext is composed of ConstructionContextLayers, but the layer information is explicitly discarded when ConstructionContext is created, in favor of a more user-friendly and explicit interface for accessing the interesting items in the ConstructionContext. Later, however - in the Analyzer, which is currently the only user of this API - there appears ConstructedObjectKey which helps tracking path-sensitive information about the constructed object. Apparently, ConstructedObjectKey has a lot in common with ConstructionContextLayer: it captures a single item that requires attention during object construction.

The common part of these two structures is factored out into a new structure, ConstructionContextItem. With that, ConstructionContextLayer becomes a wrapper around ConstructionContextItem that additionally temporarily organizes the items as a linked list, and ConstructedObjectKey becomes a wrapper around ConstructionContextItemthat additionally carries path-sensitive stack frame information.

Once ConstructionContextItem is factored out, i also made it a bit more explicit when it comes to what sort of information does it carry. It now contains an enumeration of item kinds ("variable", "destructor", "materialization", "elidable copy"). Such clarification was necessary for supporting argument constructors because otherwise it's hard to discriminate between an elidable copy layer (identified by a construct-expression and, occasionally, index 0) and a layer for the first argument of a constructor (identified by a construct-expression and, intentionally, index 0). I believe it was a good idea in general to be more explicit about what the layer means, rather than give its clients an ad-hoc pile of raw data to work with. It also allows fancy switches in createFromLayers() that check that all cases were handled, and many assertions become more explicit.

I did not, however, want to introduce a full-scale class hierarchy of ConstructionContextItems because it'd result in a ridiculous amount of boilerplate. Having them easy to construct via implicit conversion, on the other hand, seems very user-friendly and i'm not seeing much error surface.

One of the questionable ideas here is to use a special item kind ElidedDestructor that is only used by the analyzer (to track destructors that correspond to elided constructors) and is never provided by the CFG (so unlike other items it has only one use). This allows us to stop using an extra program state set for elided destructors, but i'm not sure it was a beautiful thing to pursue.

Diff Detail