Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit d16966f

Browse files
committed
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<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
1 parent 3b8e740 commit d16966f

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

include/clang/Sema/ParsedAttr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct AvailabilityData {
7878
};
7979

8080
struct TypeTagForDatatypeData {
81-
ParsedType *MatchingCType;
81+
ParsedType MatchingCType;
8282
unsigned LayoutCompatible : 1;
8383
unsigned MustBeNull : 1;
8484
};
@@ -502,7 +502,7 @@ class ParsedAttr final
502502
const ParsedType &getMatchingCType() const {
503503
assert(getKind() == AT_TypeTagForDatatype &&
504504
"Not a type_tag_for_datatype attribute");
505-
return *getTypeTagForDatatypeDataSlot().MatchingCType;
505+
return getTypeTagForDatatypeDataSlot().MatchingCType;
506506
}
507507

508508
bool getLayoutCompatible() const {

0 commit comments

Comments
 (0)