[clang] [Sema] Diagnose taking the address of a #pragma pack member (PR #219096)

Matt Turner via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 14 17:59:17 PDT 2026


================
@@ -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


More information about the cfe-commits mailing list