Author: chandlerc Date: Tue Dec 29 21:09:25 2015 New Revision: 256611 URL: http://llvm.org/viewvc/llvm-project?rev=256611&view=rev Log: [ptr-traits] Switch the Redeclarable template to using a void pointer in its PointerUnion rather than an ASTContext pointer.
Using pointers with PointerUnion really should be checking the pointee type's alignment, and we can't do this without the complete type. The Redeclarable template inherently can't know the complete type of ASTContext because of its layering, and because it is a template its methods can't reasonably be out-of-line the way we traditionally solve circular references within the AST library. After discussing this with Richard Smith, his suggestion which I have implemented here was to just drop to a void* for the PointerUnion. This essentially documents that we're going to completely ignore the type (including its potential alignment consequences) for this code. There are still of course dynamic guards that this ended up working correctly, and because of the way the code is factored this doesn't leak outside of the very narrow implementation guts of Redeclarable. This is part of a series of patches to allow LLVM to check for complete pointee types when computing its pointer traits. This is absolutely necessary to get correct (or reproducible) results for things like how many low bits are guaranteed to be zero. Modified: cfe/trunk/include/clang/AST/Redeclarable.h Modified: cfe/trunk/include/clang/AST/Redeclarable.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Redeclarable.h?rev=256611&r1=256610&r2=256611&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Redeclarable.h (original) +++ cfe/trunk/include/clang/AST/Redeclarable.h Tue Dec 29 21:09:25 2015 @@ -20,6 +20,7 @@ #include <iterator> namespace clang { +class ASTContext; /// \brief Provides common interface for the Decls that can be redeclared. template<typename decl_type> @@ -32,7 +33,11 @@ protected: &ExternalASTSource::CompleteRedeclChain> KnownLatest; - typedef const ASTContext *UninitializedLatest; + /// We store a pointer to the ASTContext in the UninitializedLatest + /// pointer, but to avoid circular type dependencies when we steal the low + /// bits of this pointer, we use a raw void* here. + typedef const void *UninitializedLatest; + typedef Decl *Previous; /// A pointer to either an uninitialized latest declaration (where either @@ -47,7 +52,7 @@ protected: enum LatestTag { LatestLink }; DeclLink(LatestTag, const ASTContext &Ctx) - : Next(NotKnownLatest(&Ctx)) {} + : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {} DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {} @@ -67,7 +72,8 @@ protected: return static_cast<decl_type*>(NKL.get<Previous>()); // Allocate the generational 'most recent' cache now, if needed. - Next = KnownLatest(*NKL.get<UninitializedLatest>(), + Next = KnownLatest(*reinterpret_cast<const ASTContext *>( + NKL.get<UninitializedLatest>()), const_cast<decl_type *>(D)); } @@ -83,7 +89,9 @@ protected: assert(NextIsLatest() && "decl became canonical unexpectedly"); if (Next.is<NotKnownLatest>()) { NotKnownLatest NKL = Next.get<NotKnownLatest>(); - Next = KnownLatest(*NKL.get<UninitializedLatest>(), D); + Next = KnownLatest(*reinterpret_cast<const ASTContext *>( + NKL.get<UninitializedLatest>()), + D); } else { auto Latest = Next.get<KnownLatest>(); Latest.set(D); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits