This addresses pr50497. The argument of a typeid expression is unevaluated, *except* when it's a polymorphic type. We handle this by parsing as unevaluated and then transforming to evaluated if we discover it should have been an evaluated context.
We do the same in TreeTransform<Derived>::TransformCXXTypeidExpr, entering unevaluated context before transforming and rebuilding the typeid. But that's incorrect and can lead us to converting to evaluated context twice -- and hitting an assert.
During normal template instantiation we're always cloning the expression, but during generic lambda processing we do not necessarily AlwaysRebuild, and end up with TransformDeclRefExpr unconditionally calling MarkDeclRefReferenced around line 10226. That triggers the assert.
// Mark it referenced in the new context regardless. // FIXME: this is a bit instantiation-specific. SemaRef.MarkDeclRefReferenced(E);
This patch makes 2 changes.
a) TreeTransform<Derived>::TransformCXXTypeidExpr only enters unevaluated context if the typeid's operand is not a polymorphic glvalue. If it is, it keeps the same evaluation context.
b) Sema::BuildCXXTypeId is altered to only transform to evaluated, if the current context is unevaluated.