riccibruno created this revision. riccibruno added a reviewer: erichkeane. riccibruno added a project: clang. Herald added a subscriber: cfe-commits.
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. Repository: rC Clang https://reviews.llvm.org/D50532 Files: include/clang/Sema/ParsedAttr.h Index: include/clang/Sema/ParsedAttr.h =================================================================== --- include/clang/Sema/ParsedAttr.h +++ include/clang/Sema/ParsedAttr.h @@ -199,7 +199,7 @@ public: struct TypeTagForDatatypeData { - ParsedType *MatchingCType; + ParsedType MatchingCType; unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; @@ -487,7 +487,7 @@ const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); - return *getTypeTagForDatatypeDataSlot().MatchingCType; + return getTypeTagForDatatypeDataSlot().MatchingCType; } bool getLayoutCompatible() const {
Index: include/clang/Sema/ParsedAttr.h =================================================================== --- include/clang/Sema/ParsedAttr.h +++ include/clang/Sema/ParsedAttr.h @@ -199,7 +199,7 @@ public: struct TypeTagForDatatypeData { - ParsedType *MatchingCType; + ParsedType MatchingCType; unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; @@ -487,7 +487,7 @@ const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); - return *getTypeTagForDatatypeDataSlot().MatchingCType; + return getTypeTagForDatatypeDataSlot().MatchingCType; } bool getLayoutCompatible() const {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits