https://github.com/mattst88 updated 
https://github.com/llvm/llvm-project/pull/219096

>From 0d43eb2adcd90810e38e4df67a217b3e4e2fc47e Mon Sep 17 00:00:00 2001
From: Matt Turner <[email protected]>
Date: Mon, 14 Sep 2026 20:39:25 -0400
Subject: [PATCH 1/2] [Sema] Diagnose taking the address of a #pragma pack
 member

-Waddress-of-packed-member only looked for PackedAttr, so members
packed by #pragma pack went undiagnosed:

  #pragma pack(1)
  struct S { char c; int x; };
  int *f(struct S *p) { return &p->x; }   // not diagnosed

Replace the attribute checks with a query of the record layout: a field
is underaligned if its record's alignment or its offset is not enough
for its type. That covers packed, #pragma pack, -fpack-struct,
the mac68k alignment pragma, and a typedef with a lowered alignment,
without naming any of them. The field to blame is the first one the
layout left underaligned.

Report the least alignment of any link in the chain, since an outer
packed record can reduce a field further than its own record did.

The check needs the layout of any record whose member has its address
taken, so skip records that are still being defined. Taking the address
of a packed member in a trailing return type used to compute the layout
of an incomplete class, which asserts.

Layout/ms-x86-lazy-empty-nonvirtual-base.cpp: F is now laid out where
it is defined, so its checks move to match the dump order.

Fixes #97091.

Assisted-by: Claude Code
---
 clang/docs/ReleaseNotes.md                    |   4 +
 clang/lib/Sema/SemaChecking.cpp               |  52 ++++---
 .../ms-x86-lazy-empty-nonvirtual-base.cpp     |  52 ++++---
 clang/test/Sema/address-packed-layout.c       |  64 ++++++++
 clang/test/Sema/address-packed.c              | 143 ++++++++++++++++++
 clang/test/SemaCXX/address-packed.cpp         |  36 +++++
 6 files changed, 307 insertions(+), 44 deletions(-)
 create mode 100644 clang/test/Sema/address-packed-layout.c

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 77a1e73bc8af6..57f53df4d7d0b 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -621,6 +621,10 @@ features cannot lower the translation-unit ABI level;
   `-Wunsafe-buffer-usage` to control warnings on `main`'s `argv` parameter,
   allowing users to suppress them with `-Wno-unsafe-buffer-usage-main-argv`.
 
+- `-Waddress-of-packed-member` now also diagnoses members packed by
+  `#pragma pack`, `#pragma options align=mac68k`, or `-fpack-struct`, and
+  members whose typedef lowers their alignment. (#GH97091)
+
 ### Improvements to Clang's time-trace
 
 ### Improvements to Coverage Mapping
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0531dfa877fbd..6d65af637d1ff 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -17102,6 +17102,17 @@ void Sema::DiscardMisalignedMemberAddress(const Type 
*T, Expr *E) {
   }
 }
 
+/// Return true if record layout leaves \p FD with less alignment than its
+/// type requires, as packing or a typedef with a lowered alignment does.
+static bool isFieldUnderaligned(const ASTContext &Ctx, const FieldDecl *FD) {
+  CharUnits TypeAlignment =
+      Ctx.getTypeAlignInChars(FD->getType().getCanonicalType());
+  CharUnits RecordAlignment =
+      Ctx.getTypeAlignInChars(Ctx.getCanonicalTagType(FD->getParent()));
+  CharUnits Offset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(FD));
+  return RecordAlignment < TypeAlignment || 
!Offset.isMultipleOf(TypeAlignment);
+}
+
 void Sema::RefersToMemberWithReducedAlignment(
     Expr *E,
     llvm::function_ref<void(Expr *, RecordDecl *, FieldDecl *, CharUnits)>
@@ -17118,7 +17129,6 @@ void Sema::RefersToMemberWithReducedAlignment(
   // will keep FieldDecl's like [d, c, b].
   SmallVector<FieldDecl *, 4> ReverseMemberChain;
   const MemberExpr *TopME = nullptr;
-  bool AnyIsPacked = false;
   do {
     QualType BaseType = ME->getBase()->getType();
     if (BaseType->isDependentType())
@@ -17126,7 +17136,8 @@ void Sema::RefersToMemberWithReducedAlignment(
     if (ME->isArrow())
       BaseType = BaseType->getPointeeType();
     auto *RD = BaseType->castAsRecordDecl();
-    if (RD->isInvalidDecl())
+    // A class still being defined has no layout to consult.
+    if (RD->isInvalidDecl() || !RD->isCompleteDefinition())
       return;
 
     ValueDecl *MD = ME->getMemberDecl();
@@ -17135,8 +17146,6 @@ void Sema::RefersToMemberWithReducedAlignment(
     if (!FD || FD->isInvalidDecl())
       return;
 
-    AnyIsPacked =
-        AnyIsPacked || (RD->hasAttr<PackedAttr>() || 
MD->hasAttr<PackedAttr>());
     ReverseMemberChain.push_back(FD);
 
     TopME = ME;
@@ -17144,10 +17153,6 @@ void Sema::RefersToMemberWithReducedAlignment(
   } while (ME);
   assert(TopME && "We did not compute a topmost MemberExpr!");
 
-  // Not the scope of this diagnostic.
-  if (!AnyIsPacked)
-    return;
-
   const Expr *TopBase = TopME->getBase()->IgnoreParenImpCasts();
   const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
   // TODO: The innermost base of the member expression may be too complicated.
@@ -17163,6 +17168,12 @@ void Sema::RefersToMemberWithReducedAlignment(
   if (ExpectedAlignment.isOne())
     return;
 
+  // Not the scope of this diagnostic.
+  if (llvm::none_of(ReverseMemberChain, [&](const FieldDecl *FD) {
+        return isFieldUnderaligned(Context, FD);
+      }))
+    return;
+
   // Synthesize offset of the whole access.
   CharUnits Offset;
   for (const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
@@ -17192,21 +17203,24 @@ void Sema::RefersToMemberWithReducedAlignment(
     // type) but some packed attribute in that chain has reduced the alignment.
     // It may happen that another packed structure increases it again. But if
     // we are here such increase has not been enough. So pointing the first
-    // FieldDecl that either is packed or else its RecordDecl is,
-    // seems reasonable.
+    // FieldDecl whose alignment was reduced seems reasonable.
     FieldDecl *FD = nullptr;
-    CharUnits Alignment;
+    // An outer link may reduce the alignment further than the culprit did.
+    CharUnits Alignment = ExpectedAlignment;
     for (FieldDecl *FDI : ReverseMemberChain) {
-      if (FDI->hasAttr<PackedAttr>() ||
-          FDI->getParent()->hasAttr<PackedAttr>()) {
-        FD = FDI;
-        Alignment = std::min(Context.getTypeAlignInChars(FD->getType()),
-                             Context.getTypeAlignInChars(
-                                 
Context.getCanonicalTagType(FD->getParent())));
-        break;
+      CharUnits FieldAlignment =
+          Context.getTypeAlignInChars(FDI->getType().getCanonicalType());
+      if (isFieldUnderaligned(Context, FDI)) {
+        if (!FD)
+          FD = FDI;
+        FieldAlignment =
+            std::min(Context.getTypeAlignInChars(FDI->getType()),
+                     Context.getTypeAlignInChars(
+                         Context.getCanonicalTagType(FDI->getParent())));
       }
+      Alignment = std::min(Alignment, FieldAlignment);
     }
-    assert(FD && "We did not find a packed FieldDecl!");
+    assert(FD && "We did not find a FieldDecl with reduced alignment!");
     Action(E, FD->getParent(), FD, Alignment);
   }
 }
diff --git a/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp 
b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
index 66e89e446d848..17fa06b49f113 100644
--- a/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
+++ b/clang/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
@@ -26,6 +26,33 @@ struct B5X { B5X() { printf("B5 = %p\n", this); } };
 struct B6X { B6X() { printf("B6 = %p\n", this); } };
 struct B8X { short a; B8X() : a(0x000000B8) { printf("B8 = %p\n", this); } };
 
+// F is laid out where it is defined, since its constructor takes the address
+// of a member.
+// CHECK-LABEL:   0 | struct F{{$}}
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-NEXT:    3 |   struct B8 (base)
+// CHECK-NEXT:    3 |     char[5] c
+// CHECK-NEXT:   12 |   struct B5 (base) (empty)
+// CHECK-NEXT:    8 |   (F vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
+// CHECK-X64-LABEL:   0 | struct F{{$}}
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B8 (base)
+// CHECK-X64-NEXT:    3 |     char[5] c
+// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (F vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
 struct AA : B8, B1, virtual B0 {
        int a;
        AA() : a(0x000000AA) { printf("AA = %p\n", this); }
@@ -502,31 +529,6 @@ struct F : B1, B6, B4, B8, B5, virtual B0 {
        F() : a(0x0000000F) { printf("&a = %p\n", &a); printf("F = %p\n", 
this); }
 };
 
-// CHECK-LABEL:   0 | struct F{{$}}
-// CHECK-NEXT:    0 |   struct B1 (base) (empty)
-// CHECK-NEXT:    2 |   struct B6 (base) (empty)
-// CHECK-NEXT:    3 |   struct B4 (base) (empty)
-// CHECK-NEXT:    3 |   struct B8 (base)
-// CHECK-NEXT:    3 |     char[5] c
-// CHECK-NEXT:   12 |   struct B5 (base) (empty)
-// CHECK-NEXT:    8 |   (F vbtable pointer)
-// CHECK-NEXT:   12 |   int a
-// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
-// CHECK-NEXT:      | [sizeof=16, align=4
-// CHECK-NEXT:      |  nvsize=16, nvalign=4]
-// CHECK-X64-LABEL:   0 | struct F{{$}}
-// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
-// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
-// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
-// CHECK-X64-NEXT:    3 |   struct B8 (base)
-// CHECK-X64-NEXT:    3 |     char[5] c
-// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
-// CHECK-X64-NEXT:    8 |   (F vbtable pointer)
-// CHECK-X64-NEXT:   16 |   int a
-// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64-NEXT:      | [sizeof=24, align=8
-// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
-
 struct G : B8, B1, virtual B0 {
        int a;
        __declspec(align(16)) int a1;
diff --git a/clang/test/Sema/address-packed-layout.c 
b/clang/test/Sema/address-packed-layout.c
new file mode 100644
index 0000000000000..76aad5352aa62
--- /dev/null
+++ b/clang/test/Sema/address-packed-layout.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -fpack-struct=1 
-DPACK_STRUCT -verify=pack-struct %s
+// RUN: %clang_cc1 -fsyntax-only -triple i386-apple-darwin -DMAC68K 
-verify=mac68k %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -target-feature 
+avx512f -DPACK16 -verify=itanium %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-windows-msvc -target-feature 
+avx512f -DPACK16 -verify=ms %s
+
+extern void f1(int *);
+
+#ifdef PACK_STRUCT
+struct S {
+  char c;
+  int x;
+};
+
+void g0(struct S *p) {
+  f1(&p->x); // pack-struct-warning {{packed member 'x' of class or structure 
'S'}}
+}
+
+// #pragma pack overrides -fpack-struct.
+#pragma pack(push, 4)
+struct Pack4 {
+  char c;
+  int x;
+};
+#pragma pack(pop)
+
+void g1(struct Pack4 *p) {
+  f1(&p->x); // no-warning
+}
+#endif
+
+#ifdef MAC68K
+#pragma options align=mac68k
+struct S {
+  char c;
+  int x;
+};
+#pragma options align=reset
+
+void g0(struct S *p) {
+  f1(&p->x); // mac68k-warning {{packed member 'x' of class or structure 'S'}}
+}
+#endif
+
+#ifdef PACK16
+typedef float V512 __attribute__((vector_size(64)));
+
+// Only the Microsoft layout ignores a pack wider than a pointer.
+#pragma pack(push, 16)
+struct Pack16 {
+  char c;
+  V512 x;
+};
+#pragma pack(pop)
+
+struct __attribute__((packed)) Outer {
+  char c;
+  struct Pack16 inner;
+};
+
+void g0(struct Outer *p) {
+  V512 *q = &p->inner.x; // itanium-warning {{packed member 'x' of class or 
structure 'Pack16'}}
+  // ms-warning@-1 {{packed member 'inner' of class or structure 'Outer'}}
+}
+#endif
diff --git a/clang/test/Sema/address-packed.c b/clang/test/Sema/address-packed.c
index f826b7d57d91c..5036152842296 100644
--- a/clang/test/Sema/address-packed.c
+++ b/clang/test/Sema/address-packed.c
@@ -346,3 +346,146 @@ void g15(void) {
   to_void_with_expr(&arguable.x, 3); // no-warning
   to_void_with_expr(&arguable.x, ({3;})); // no-warning
 }
+
+#pragma pack(push, 1)
+struct PragmaPack1 {
+  char c0;
+  int x;
+};
+#pragma pack(pop)
+
+void g16(struct PragmaPack1 *p) {
+  f1(&p->x); // expected-warning {{packed member 'x' of class or structure 
'PragmaPack1'}}
+  f2(&p->c0); // no-warning
+}
+
+// #pragma pack(4) does not reduce an int.
+#pragma pack(push, 4)
+struct PragmaPack4 {
+  char c0;
+  int x;
+  char c1;
+};
+#pragma pack(pop)
+
+void g17(struct PragmaPack4 *p) {
+  f1(&p->x); // no-warning
+}
+
+// The record is two-aligned, so x is misaligned despite an offset of four.
+#pragma pack(push, 2)
+struct PragmaPack2 {
+  char c0;
+  char c1;
+  int x;
+};
+#pragma pack(pop)
+
+void g18(struct PragmaPack2 *p) {
+  f1(&p->x); // expected-warning {{packed member 'x' of class or structure 
'PragmaPack2'}}
+}
+
+struct PragmaPackOuter {
+  char c0;
+  struct PragmaPack1 inner;
+};
+
+void g19(struct PragmaPackOuter *p) {
+  f1(&p->inner.x); // expected-warning {{packed member 'x' of class or 
structure 'PragmaPack1'}}
+}
+
+extern void f3(short *);
+
+// short is two-aligned and so is PragmaPack2.
+void g20(struct PragmaPack2 *p) {
+  f3((short *)&p->x); // no-warning
+}
+
+// The outer packed record lowers it to one.
+struct __attribute__((packed)) PragmaPackInPacked {
+  char c0;
+  struct PragmaPack2 inner;
+};
+
+void g21(struct PragmaPackInPacked *p) {
+  f3((short *)&p->inner.x); // expected-warning {{packed member 'x' of class 
or structure 'PragmaPack2'}}
+}
+
+// #pragma pack(4) does not reduce x, so the outer packed record takes the
+// blame.
+struct __attribute__((packed)) PragmaPack4InPacked {
+  char c0;
+  struct PragmaPack4 inner;
+};
+
+void g22(struct PragmaPack4InPacked *p) {
+  f1(&p->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PragmaPack4InPacked'}}
+}
+
+// The typedef lowers inner to one, whatever the packing.
+struct Natural {
+  char c0;
+  int x;
+};
+typedef struct Natural __attribute__((aligned(1))) UnalignedNatural;
+
+struct __attribute__((packed)) PackedHoldsUnaligned {
+  char c0;
+  UnalignedNatural inner;
+};
+
+#pragma pack(push, 1)
+struct PragmaPackHoldsUnaligned {
+  char c0;
+  UnalignedNatural inner;
+};
+#pragma pack(pop)
+
+void g23(struct PackedHoldsUnaligned *p, struct PragmaPackHoldsUnaligned *q) {
+  f1(&p->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PackedHoldsUnaligned'}}
+  f1(&q->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PragmaPackHoldsUnaligned'}}
+}
+
+// A typedef lowers alignment without any packing.
+struct HoldsUnaligned {
+  char c0;
+  UnalignedNatural inner;
+};
+
+struct HoldsHoldsUnaligned {
+  char c0;
+  struct HoldsUnaligned holder;
+};
+
+typedef int __attribute__((aligned(1))) UnalignedInt;
+
+struct HoldsUnalignedInt {
+  char c0;
+  UnalignedInt x;
+};
+
+void g24(struct HoldsUnaligned *p, struct HoldsHoldsUnaligned *q,
+         struct HoldsUnalignedInt *r) {
+  f1(&p->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'HoldsUnaligned'}}
+  f1(&q->holder.inner.x); // expected-warning {{packed member 'inner' of class 
or structure 'HoldsUnaligned'}}
+  f2(&p->inner.c0); // no-warning
+  UnalignedInt *ui = &r->x; // no-warning
+}
+
+// The packed attribute leaves x where it would be anyway, so the outer packed
+// record takes the blame.
+struct HoldsAlignedPackedField {
+  int i;
+  int x __attribute__((packed));
+};
+
+struct __attribute__((packed)) PackedHoldsAlignedPackedField {
+  char c0;
+  struct HoldsAlignedPackedField inner;
+};
+
+void g25(struct HoldsAlignedPackedField *p,
+         struct PackedHoldsAlignedPackedField *q) {
+  f1(&p->x); // no-warning
+  f1(&q->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PackedHoldsAlignedPackedField'}}
+}
diff --git a/clang/test/SemaCXX/address-packed.cpp 
b/clang/test/SemaCXX/address-packed.cpp
index f0d1496fd8928..921dc09f35d08 100644
--- a/clang/test/SemaCXX/address-packed.cpp
+++ b/clang/test/SemaCXX/address-packed.cpp
@@ -121,3 +121,39 @@ struct S2 {
   Incomplete *e() const;
 } __attribute__((packed));
 Incomplete *S2::e() const { return (Incomplete *)&d; } // no-warning
+
+#pragma pack(push, 1)
+struct PragmaPacked {
+  char c;
+  int x;
+  int *get() { return &x; } // expected-warning {{packed member 'x' of class 
or structure 'PragmaPacked'}}
+};
+#pragma pack(pop)
+
+void g2(PragmaPacked *p) {
+  f1(&p->x); // expected-warning {{packed member 'x' of class or structure 
'PragmaPacked'}}
+  f2(&p->c); // no-warning
+}
+
+// #pragma pack caps the base subobject too, so alignof(DerivedFromUnpacked)
+// is one and &p->x really is a one-aligned int *. Not diagnosed: the chain
+// has a link per member access and none for the derived-to-base conversion.
+struct Unpacked {
+  char c;
+  int x;
+};
+#pragma pack(push, 1)
+struct DerivedFromUnpacked : Unpacked {};
+#pragma pack(pop)
+
+void g3(DerivedFromUnpacked *p) {
+  f1(&p->x); // no-warning
+}
+
+// A class has no layout until it is complete.
+struct __attribute__((packed)) Incomplete2 {
+  char c;
+  int x;
+  auto get() -> decltype(&this->x); // no-warning
+  auto get2() -> decltype(&x) { return &x; } // expected-warning {{packed 
member 'x' of class or structure 'Incomplete2'}}
+};

>From f91d258bee4fea833ca2a97f6a4a100aa5851ada Mon Sep 17 00:00:00 2001
From: Matt Turner <[email protected]>
Date: Mon, 12 Oct 2026 00:25:18 -0400
Subject: [PATCH 2/2] [Sema] Move typedef-alignment tests under explicit
 triples

The Microsoft layout does not let a typedef lower a field's alignment,
so these fields are aligned there and nothing is diagnosed. 
Sema/address-packed.c
runs with the host triple and failed on Windows. Check both layouts in
address-packed-layout.c instead.

Assisted-by: Claude Code
---
 clang/test/Sema/address-packed-layout.c | 40 +++++++++++++++++++++++++
 clang/test/Sema/address-packed.c        | 31 ++-----------------
 2 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/clang/test/Sema/address-packed-layout.c 
b/clang/test/Sema/address-packed-layout.c
index 76aad5352aa62..7328a257743cf 100644
--- a/clang/test/Sema/address-packed-layout.c
+++ b/clang/test/Sema/address-packed-layout.c
@@ -2,6 +2,8 @@
 // RUN: %clang_cc1 -fsyntax-only -triple i386-apple-darwin -DMAC68K 
-verify=mac68k %s
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -target-feature 
+avx512f -DPACK16 -verify=itanium %s
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-windows-msvc -target-feature 
+avx512f -DPACK16 -verify=ms %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -DTYPEDEF 
-verify=typedef-itanium %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-windows-msvc -DTYPEDEF 
-verify=typedef-ms %s
 
 extern void f1(int *);
 
@@ -62,3 +64,41 @@ void g0(struct Outer *p) {
   // ms-warning@-1 {{packed member 'inner' of class or structure 'Outer'}}
 }
 #endif
+
+#ifdef TYPEDEF
+// typedef-ms-no-diagnostics
+extern void f2(char *);
+
+struct Natural {
+  char c0;
+  int x;
+};
+typedef struct Natural __attribute__((aligned(1))) UnalignedNatural;
+
+// A typedef lowers alignment without any packing, but not in the Microsoft
+// layout.
+struct HoldsUnaligned {
+  char c0;
+  UnalignedNatural inner;
+};
+
+struct HoldsHoldsUnaligned {
+  char c0;
+  struct HoldsUnaligned holder;
+};
+
+typedef int __attribute__((aligned(1))) UnalignedInt;
+
+struct HoldsUnalignedInt {
+  char c0;
+  UnalignedInt x;
+};
+
+void g0(struct HoldsUnaligned *p, struct HoldsHoldsUnaligned *q,
+        struct HoldsUnalignedInt *r) {
+  f1(&p->inner.x); // typedef-itanium-warning {{packed member 'inner' of class 
or structure 'HoldsUnaligned'}}
+  f1(&q->holder.inner.x); // typedef-itanium-warning {{packed member 'inner' 
of class or structure 'HoldsUnaligned'}}
+  f2(&p->inner.c0); // no-warning
+  UnalignedInt *ui = &r->x; // no-warning
+}
+#endif
diff --git a/clang/test/Sema/address-packed.c b/clang/test/Sema/address-packed.c
index 5036152842296..26253e2e49b0d 100644
--- a/clang/test/Sema/address-packed.c
+++ b/clang/test/Sema/address-packed.c
@@ -422,7 +422,8 @@ void g22(struct PragmaPack4InPacked *p) {
   f1(&p->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PragmaPack4InPacked'}}
 }
 
-// The typedef lowers inner to one, whatever the packing.
+// inner is one-aligned: by the typedef, or by the packing in the Microsoft
+// layout, which ignores the typedef.
 struct Natural {
   char c0;
   int x;
@@ -446,32 +447,6 @@ void g23(struct PackedHoldsUnaligned *p, struct 
PragmaPackHoldsUnaligned *q) {
   f1(&q->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PragmaPackHoldsUnaligned'}}
 }
 
-// A typedef lowers alignment without any packing.
-struct HoldsUnaligned {
-  char c0;
-  UnalignedNatural inner;
-};
-
-struct HoldsHoldsUnaligned {
-  char c0;
-  struct HoldsUnaligned holder;
-};
-
-typedef int __attribute__((aligned(1))) UnalignedInt;
-
-struct HoldsUnalignedInt {
-  char c0;
-  UnalignedInt x;
-};
-
-void g24(struct HoldsUnaligned *p, struct HoldsHoldsUnaligned *q,
-         struct HoldsUnalignedInt *r) {
-  f1(&p->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'HoldsUnaligned'}}
-  f1(&q->holder.inner.x); // expected-warning {{packed member 'inner' of class 
or structure 'HoldsUnaligned'}}
-  f2(&p->inner.c0); // no-warning
-  UnalignedInt *ui = &r->x; // no-warning
-}
-
 // The packed attribute leaves x where it would be anyway, so the outer packed
 // record takes the blame.
 struct HoldsAlignedPackedField {
@@ -484,7 +459,7 @@ struct __attribute__((packed)) 
PackedHoldsAlignedPackedField {
   struct HoldsAlignedPackedField inner;
 };
 
-void g25(struct HoldsAlignedPackedField *p,
+void g24(struct HoldsAlignedPackedField *p,
          struct PackedHoldsAlignedPackedField *q) {
   f1(&p->x); // no-warning
   f1(&q->inner.x); // expected-warning {{packed member 'inner' of class or 
structure 'PackedHoldsAlignedPackedField'}}

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

Reply via email to