[LifetimeSafety] Overhaul CFG and analysis to also work with trivially destructed temporary objects (#177985)
Change summary:
Modification to CFG:
1. Added `CFGFullExprCleanup` which has a pointer to `BumpVector<const
MaterializeTemporaryExpr *>` to track all MTE that **might** (in the
sense that we take union on branches) be spawned by an
`ExprWithCleanups`
2. Modified logic in `CFGBuilder` to appropriately insert this marker.
It inserts the marker primarily via `CFGBuilder::VisitExprWithCleanups`,
and also `CFGBuilder::addInitializer` and `CFGBuilder::VisitDeclSubExpr`
as these bypass visiting the `ExprWithCleanups`. The bump vector is
allocated appropriately using the bump allocator of the CFG to respect
its lifetime rules.
3. Visiting to track the temporaries is done in
`CFGBuilder::VisitForTemporaries`. Behaviour is modulated via the
`BuildOpts` so as to enable tracking only when necessary. The
encountered non-lifetime extended MTE are stored in a small vector
member of `TempDtorContext`.
Modification to analysis:
1. Logic to issue the loans remains mostly the same, with the caveat
that we now **always** issue a loan to any MTE that expires at the end
of full expression.
2. Introduced `handleFullExprCleanup` to replace `handleTemporaryDtor`.
It loops through all active loans, expiring them if the path matches an
MTE in the `CFGFullExprCleanup` node's `ExpiringMTEs`.
Fixes:
#175893
#178159