[PATCH] D105498: [clang] Remove assumption about SourceLocation alignment.

Simon Tatham via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 6 09:28:19 PDT 2021


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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D105498.356764.patch
Type: text/x-patch
Size: 2180 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210706/7738ae9f/attachment.bin>


More information about the cfe-commits mailing list