Page MenuHomePhabricator

[clang] Fix ICE with typeid & polymorphic class (pr50497)
ClosedPublic

Authored by urnathan on May 27 2021, 8:33 AM.

Details

Summary

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.

Diff Detail

Event Timeline

urnathan requested review of this revision.May 27 2021, 8:33 AM
urnathan created this revision.
bruno accepted this revision.Jun 1 2021, 12:36 PM

LGTM

This revision is now accepted and ready to land.Jun 1 2021, 12:36 PM
This revision was landed with ongoing or failed builds.Jun 1 2021, 12:55 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJun 1 2021, 12:55 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript