[PATCH] D50532: Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData

Bruno Ricci via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 9 13:11:18 PDT 2018


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 {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50532.159988.patch
Type: text/x-patch
Size: 716 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180809/a318d88f/attachment.bin>


More information about the cfe-commits mailing list