]> granicus.if.org Git - clang/commitdiff
Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData
authorBruno Ricci <riccibrun@gmail.com>
Fri, 10 Aug 2018 11:20:20 +0000 (11:20 +0000)
committerBruno Ricci <riccibrun@gmail.com>
Fri, 10 Aug 2018 11:20:20 +0000 (11:20 +0000)
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.

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

include/clang/Sema/ParsedAttr.h

index 903702715ccf0e8c1e732530d0fa36e4af6b9552..7561e835747a0a09ea18dfbc770228e13a0b76df 100644 (file)
@@ -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 {