simon_tatham created this revision. simon_tatham added reviewers: rsmith, lebedev.ri, akyrtzi. simon_tatham requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is part of a patch series working towards the ability to make SourceLocation into a 64-bit type to handle larger translation units. In `ObjCMethodDecl`, an array of pointers (parameters) and an array of SourceLocations are stored end to end in a single allocated piece of memory. The offset within that memory where the second array begins was being computed in a really simple way, based on the assumption that pointers had at least as much alignment requirement as SourceLocations. But when pointers and SourceLocations can each be either 32 or 64 bits, this won't be a reliable assumption any more. This patch explicitly computes the offset in a way that should work for any combination of alignment requirements. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D105498 Files: clang/include/clang/AST/DeclObjC.h clang/lib/AST/DeclObjC.cpp Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -874,11 +875,8 @@ if (Params.empty() && SelLocs.empty()) return; - static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation), - "Alignment not sufficient for SourceLocation"); - - unsigned Size = sizeof(ParmVarDecl *) * NumParams + - sizeof(SourceLocation) * SelLocs.size(); + unsigned Size = + getStoredSelLocsOffset() + sizeof(SourceLocation) * SelLocs.size(); ParamsAndSelLocs = C.Allocate(Size); std::copy(Params.begin(), Params.end(), getParams()); std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); Index: clang/include/clang/AST/DeclObjC.h =================================================================== --- clang/include/clang/AST/DeclObjC.h +++ clang/include/clang/AST/DeclObjC.h @@ -190,13 +190,20 @@ return getSelLocsKind() != SelLoc_NonStandard; } + size_t getStoredSelLocsOffset() const { + return llvm::alignTo<alignof(SourceLocation)>(sizeof(ParmVarDecl *) * + NumParams); + } + /// Get a pointer to the stored selector identifiers locations array. /// No locations will be stored if HasStandardSelLocs is true. SourceLocation *getStoredSelLocs() { - return reinterpret_cast<SourceLocation *>(getParams() + NumParams); + return reinterpret_cast<SourceLocation *>( + reinterpret_cast<char *>(ParamsAndSelLocs) + getStoredSelLocsOffset()); } const SourceLocation *getStoredSelLocs() const { - return reinterpret_cast<const SourceLocation *>(getParams() + NumParams); + return reinterpret_cast<SourceLocation *>( + reinterpret_cast<char *>(ParamsAndSelLocs) + getStoredSelLocsOffset()); } /// Get a pointer to the stored selector identifiers locations array.
Index: clang/lib/AST/DeclObjC.cpp =================================================================== --- clang/lib/AST/DeclObjC.cpp +++ clang/lib/AST/DeclObjC.cpp @@ -28,6 +28,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -874,11 +875,8 @@ if (Params.empty() && SelLocs.empty()) return; - static_assert(alignof(ParmVarDecl *) >= alignof(SourceLocation), - "Alignment not sufficient for SourceLocation"); - - unsigned Size = sizeof(ParmVarDecl *) * NumParams + - sizeof(SourceLocation) * SelLocs.size(); + unsigned Size = + getStoredSelLocsOffset() + sizeof(SourceLocation) * SelLocs.size(); ParamsAndSelLocs = C.Allocate(Size); std::copy(Params.begin(), Params.end(), getParams()); std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); Index: clang/include/clang/AST/DeclObjC.h =================================================================== --- clang/include/clang/AST/DeclObjC.h +++ clang/include/clang/AST/DeclObjC.h @@ -190,13 +190,20 @@ return getSelLocsKind() != SelLoc_NonStandard; } + size_t getStoredSelLocsOffset() const { + return llvm::alignTo<alignof(SourceLocation)>(sizeof(ParmVarDecl *) * + NumParams); + } + /// Get a pointer to the stored selector identifiers locations array. /// No locations will be stored if HasStandardSelLocs is true. SourceLocation *getStoredSelLocs() { - return reinterpret_cast<SourceLocation *>(getParams() + NumParams); + return reinterpret_cast<SourceLocation *>( + reinterpret_cast<char *>(ParamsAndSelLocs) + getStoredSelLocsOffset()); } const SourceLocation *getStoredSelLocs() const { - return reinterpret_cast<const SourceLocation *>(getParams() + NumParams); + return reinterpret_cast<SourceLocation *>( + reinterpret_cast<char *>(ParamsAndSelLocs) + getStoredSelLocsOffset()); } /// Get a pointer to the stored selector identifiers locations array.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits