This is an archive of the discontinued LLVM Phabricator instance.

Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData
ClosedPublic

Authored by riccibruno on Aug 9 2018, 1:11 PM.

Details

Summary

This patch fixes a wrong type bug inside ParsedAttr::TypeTagForDatatypeData.
The details to the best of my knowledge are as follow. The incredible thing
is that everything works out just fine by chance due to a sequence of lucky
coincidences in the layout of various types.

The struct ParsedAttr::TypeTagForDatatypeData contains among other things
a ParsedType *MatchingCType, where ParsedType is just OpaquePtr<QualType>.

However the member MatchingCType is initialized in the constructor for
type_tag_for_datatype attribute as follows:

new (&ExtraData.MatchingCType) ParsedType(matchingCType);

This results in the ParsedType being constructed in the location of the
ParsedType * Later ParsedAttr::getMatchingCType do `return
*getTypeTagForDatatypeDataSlot().MatchingCType;` which instead of
dereferencing the ParsedType * will dereference the QualType inside
the ParsedType. Now this QualType in this case contains no qualifiers
and therefore is a valid Type *. Therefore getMatchingCType returns a
Type or at least the stuff that is in the first sizeof(void*) bytes of it,
But it turns out that Type inherits from ExtQualsCommonBase and that the
first member of ExtQualsCommonBase is a const Type *const BaseType. This
Type * in this case points to the original Type pointed to by the
QualType and so everything works fine even though all the types were wrong.

This bug was only found because I changed the layout of Type,
which obviously broke all of this long chain of improbable events.

Diff Detail

Repository
rC Clang

Event Timeline

riccibruno created this revision.Aug 9 2018, 1:11 PM
erichkeane accepted this revision.Aug 9 2018, 1:27 PM
This revision is now accepted and ready to land.Aug 9 2018, 1:27 PM
This revision was automatically updated to reflect the committed changes.