In code like
const int &x = A().x;
the destructor for A() was not present in the CFG due to two problems in the pattern-matching in getReferenceInitTemporaryType():
- The no-op cast from T to const T is not necessarily performed on a record type. It may be performed on essentially any type. In the current example, it is performed on an xvalue of type int in order to turn it into a const int.
- Since rC288563 member access is no longer performed over rvalues, but goes after the MaterializeTemporaryExpr instead.
This is not an analyzer-specific change. It may add/remove compiler warnings, but i don't think it makes any sense to hide this behind an analyzer-specific flag.
Can you replace this with Expr::skipRValueSubobjectAdjustments? That's how we compute this elsewhere. (You'll need to skip a top-level ExprWithCleanups and check for the search terminating in a MaterializeTemporaryExpr yourself, but this will reduce duplication and fix a couple more cases this function is getting wrong).