================
@@ -16983,6 +16983,26 @@ void Sema::DiscardMisalignedMemberAddress(const Type 
*T, Expr *E) {
   }
 }
 
+/// If packing reduces \p FD below the alignment required by its type, return
+/// the alignment it is reduced to. __attribute__((packed)) reduces every
+/// field; #pragma pack(N) only reduces fields that require more than N.
+static std::optional<CharUnits> getPackedFieldAlignment(const ASTContext &Ctx,
+                                                        const FieldDecl *FD) {
+  const RecordDecl *RD = FD->getParent();
+  bool IsPacked = FD->hasAttr<PackedAttr>() || RD->hasAttr<PackedAttr>();
+  const auto *MFAA = RD->getAttr<MaxFieldAlignmentAttr>();
+  if (!IsPacked && !MFAA)
+    return std::nullopt;
+
+  CharUnits TypeAlignment = Ctx.getTypeAlignInChars(FD->getType());
+  if (!IsPacked &&
+      Ctx.toCharUnitsFromBits(MFAA->getAlignment()) >= TypeAlignment)
+    return std::nullopt;
----------------
mattst88 wrote:

Included it. A typedef that lowers alignment now counts like packing, so 
`g23`'s `inner` is the culprit directly and the fallback is gone. A struct with 
no packing at all is also diagnosed when its member chain goes through such a 
typedef.

Looking at this I also found `-fpack-struct` and `#pragma options align=mac68k` 
reduce alignment without leaving a `MaxFieldAlignmentAttr`, so I covered those 
too, along with the Microsoft layout ignoring `#pragma pack` wider than a 
pointer. Tests are in `address-packed-layout.c`.

The warning text still says "packed member" for all of these. I can reword it 
in a follow-up if you'd like.


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

Reply via email to