From: Bruno Ricci Date: Fri, 10 Aug 2018 11:20:20 +0000 (+0000) Subject: Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d16966f91de34baf5828af710296315081be4862;p=clang Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData 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. 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. Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D50532 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339423 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/ParsedAttr.h b/include/clang/Sema/ParsedAttr.h index 903702715c..7561e83574 100644 --- a/include/clang/Sema/ParsedAttr.h +++ b/include/clang/Sema/ParsedAttr.h @@ -78,7 +78,7 @@ struct AvailabilityData { }; struct TypeTagForDatatypeData { - ParsedType *MatchingCType; + ParsedType MatchingCType; unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; @@ -502,7 +502,7 @@ public: const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); - return *getTypeTagForDatatypeDataSlot().MatchingCType; + return getTypeTagForDatatypeDataSlot().MatchingCType; } bool getLayoutCompatible() const {