MarkVarDeclODRUsed indirectly calls captureInBlock, which creates a copy expression. The copy expression is insulated in it's own ExpressionEvaluationContext, so it saves, mutates, and restores MaybeODRUseExprs as CleanupVarDeclMarking is iterating through it, leading to a crash. Fix this by iterating through a local copy of MaybeODRUseExprs.
rdar://47493525
It looks like SmallPtrSet's move constructor does actually guarantee to leave the source empty; you could probably just assert that. But I don't think there's an algorithmic cost, so this is fine, too.
Please leave an assertion at the bottom of this function that the set is empty.