This is an archive of the discontinued LLVM Phabricator instance.

[AST] Fix an assertion violation in FieldDecl::getParent.
ClosedPublic

Authored by hokein on May 8 2020, 6:38 AM.

Details

Summary

FieldDecl::getParent assumes that the FiledDecl::getDeclContext returns a
RecordDecl, this is true for C/C++, but not for ObjCIvarDecl:

The Decls hierarchy is like following

FieldDecl <-- ObjCIvarDecl

DeclContext <-- ObjCContainerDecl <-- ObjCInterfaceDecl

^
|----- TagDecl <-- RecordDecl

calling getParent() on ObjCIvarDecl will:

  1. invoke getDeclContext(), which returns a DeclContext*, which points to an ObjCInterfaceDecl;
  2. then downcast the "DeclContext" pointer to a RecordDecl*, and we will hit

the "is_a<RecordDecl>" assertion in llvm::cast (undefined behavior
in release build without assertion enabled);

Diff Detail

Event Timeline

hokein created this revision.May 8 2020, 6:38 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 8 2020, 6:38 AM
sammccall accepted this revision.May 18 2020, 12:59 PM
sammccall added a subscriber: rsmith.

Sorry for stalling this. This is a sad situation, the API is actively misleading about the invariants.

Even the new API isn't very safe: getParent() isn't a great name if it only works on *some* things that have parents.
@rsmith any opinion on what we should do with this one? Would a rename to getParentRecord() help much? Something more invasive?

Approving since this is already a bit better and we can fix a crash.

This revision is now accepted and ready to land.May 18 2020, 12:59 PM
This revision was automatically updated to reflect the committed changes.