================
@@ -382,7 +391,23 @@ RecordType::getTypeSizeInBits(const mlir::DataLayout 
&dataLayout,
     mlir::Type largest = getLargestMember(dataLayout);
     if (!largest)
       return llvm::TypeSize::getFixed(0);
-    return dataLayout.getTypeSizeInBits(largest);
+    // `getLargestMember` returns the highest-aligned variant (which dictates
+    // the union's alignment), not necessarily the largest by size.  When the
+    // union is `padded` -- i.e., its highest-aligned variant is strictly
+    // smaller than its layout size, as happens for any union containing both
+    // a small high-alignment scalar and a larger low-alignment array (e.g.,
+    // `union { char[16]; size_t; }`) -- `lowerUnion` appended a trailing
+    // byte-array member to extend the highest-aligned variant up to the
+    // layout size, and `LowerToLLVM` mirrors this by emitting the union as
+    // `{largest, padding}`.  Include that padding here so `getTypeSize`
+    // reports the same size `LowerToLLVM` produces; otherwise a parent
+    // record containing the union gets a spurious tail-padding member added
+    // by `insertPadding`, making `sizeof(parent)` and array GEPs off by the
+    // missing bytes.
+    llvm::TypeSize size = dataLayout.getTypeSizeInBits(largest);
----------------
erichkeane wrote:

While this fixes the problem, this actually ended up being the same 'problem' 
that I ran into.

I think this is actually not the solution.  The problem is 'getLongestMember' 
is wrong, and I think we should be reverting this.

https://github.com/llvm/llvm-project/pull/198361
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to