[clang] [Clang] Warn when an explicit alignment is weakened by other directives (PR #198417)

David Meng via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 6 15:11:48 PDT 2026


https://github.com/davidmenggx updated https://github.com/llvm/llvm-project/pull/198417

>From 5e8f971fc73053dee77a0a1450abedc80bf74c5d Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Mon, 18 May 2026 16:15:53 -0700
Subject: [PATCH 1/3] [Clang] Warn when an explicit alignment is weakened by
 other directives

This patch introduces `-Wweakened-alignment`, a diagnostic that warns
when an explicit `alignas` attribute is overridden and reduced by
a `#pragma pack` directive.

This behavior is specific to the Itanium ABI. On MSVC, `alignas` takes
priority so no warning is needed.

Fixes #196578
---
 .../include/clang/Basic/DiagnosticASTKinds.td |  5 +
 clang/include/clang/Basic/DiagnosticGroups.td |  1 +
 clang/lib/AST/RecordLayoutBuilder.cpp         | 15 +++
 .../test/SemaCXX/warn-weakened-alignment.cpp  | 94 +++++++++++++++++++
 4 files changed, 115 insertions(+)
 create mode 100644 clang/test/SemaCXX/warn-weakened-alignment.cpp

diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index bde418695f647..3a44a12e5a33d 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -1098,4 +1098,9 @@ def warn_unpacked_field
 def warn_unaligned_access : Warning<
   "field %1 within %0 is less aligned than %2 and is usually due to %0 being "
   "packed, which can lead to unaligned accesses">, InGroup<UnalignedAccess>, DefaultIgnore;
+
+// -Wweakened-alignment
+def warn_explicit_alignment_weakened : Warning<
+  "explicit alignment of %0 (%1 bytes) was weakened to %2 bytes">,
+  InGroup<WeakenedAlignment>;
 }
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 3136d109e795b..61899587137e4 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -845,6 +845,7 @@ def Packed : DiagGroup<"packed", [PackedNonPod]>;
 def PaddedBitField : DiagGroup<"padded-bitfield">;
 def Padded : DiagGroup<"padded", [PaddedBitField]>;
 def UnalignedAccess : DiagGroup<"unaligned-access">;
+def WeakenedAlignment : DiagGroup<"weakened-alignment">;
 def MSBitfieldCompatibility : DiagGroup<"ms-bitfield-padding"> {
   code Documentation = [{
     Under the Microsoft ABI, adjacent bit-fields are not packed if the
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f417588accd78..0ce3752b40961 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1268,6 +1268,14 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
     UnpackedAlignTo = std::min(UnpackedAlignTo, MaxFieldAlignment);
   }
 
+  CharUnits MaxAlignmentInChars =
+      Context.toCharUnitsFromBits(Base->Class->getMaxAlignment());
+  if (!MaxAlignmentInChars.isZero() && MaxAlignmentInChars > BaseAlign) {
+    Diag(Base->Class->getLocation(), diag::warn_explicit_alignment_weakened)
+        << Base->Class->getName() << MaxAlignmentInChars.getQuantity()
+        << BaseAlign.getQuantity();
+  }
+
   CharUnits AlignTo =
       !DefaultsToAIXPowerAlignment ? BaseAlign : PreferredBaseAlign;
   if (!HasExternalLayout) {
@@ -2047,6 +2055,13 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
 
   CharUnits AlignTo =
       !DefaultsToAIXPowerAlignment ? FieldAlign : PreferredAlign;
+
+  if (!MaxAlignmentInChars.isZero() && MaxAlignmentInChars > AlignTo) {
+    Diag(D->getLocation(), diag::warn_explicit_alignment_weakened)
+        << D->getName() << MaxAlignmentInChars.getQuantity()
+        << AlignTo.getQuantity();
+  }
+
   // Round up the current record size to the field's alignment boundary.
   FieldOffset = FieldOffset.alignTo(AlignTo);
   UnpackedFieldOffset = UnpackedFieldOffset.alignTo(UnpackedFieldAlign);
diff --git a/clang/test/SemaCXX/warn-weakened-alignment.cpp b/clang/test/SemaCXX/warn-weakened-alignment.cpp
new file mode 100644
index 0000000000000..2ca8e86e9511e
--- /dev/null
+++ b/clang/test/SemaCXX/warn-weakened-alignment.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -Wweakened-alignment -verify=itanium -DITANIUM %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fsyntax-only -Wweakened-alignment -verify=msvc -DMSVC %s
+
+// msvc-no-diagnostics
+
+#pragma pack(2)
+struct D1 {
+  char m1;
+  alignas(8) int m4; // itanium-warning {{explicit alignment of m4 (8 bytes) was weakened to 2 bytes}}
+};
+
+#ifdef ITANIUM
+static_assert(alignof(D1) == 2, "");
+#else
+static_assert(alignof(D1) == 8, "");
+#endif
+#pragma pack()
+
+struct D2 {
+  char m1;
+  alignas(16) int m4; 
+} __attribute__((packed));
+static_assert(alignof(D2) == 16, "");
+
+#pragma pack(8)
+struct D3 {
+  char m1;
+  alignas(4) int m4; 
+};
+static_assert(alignof(D3) == 4, "");
+#pragma pack()
+
+struct alignas(16) Base1 { // itanium-warning {{explicit alignment of Base1 (16 bytes) was weakened to 2 bytes}}
+  int x;
+};
+
+#pragma pack(2)
+struct Derived1 : Base1 {
+  char y;
+};
+#pragma pack()
+Derived1 d1;
+
+#ifdef ITANIUM
+static_assert(alignof(Derived1) == 2, "");
+#else
+static_assert(alignof(Derived1) == 16, "");
+#endif
+
+struct alignas(8) Base2 { // itanium-warning {{explicit alignment of Base2 (8 bytes) was weakened to 4 bytes}}
+  int x;
+};
+
+#pragma pack(4)
+struct Derived2 : Base2 {
+  char y;
+};
+#pragma pack()
+Derived2 d2;
+
+#ifdef ITANIUM
+static_assert(alignof(Derived2) == 4, "");
+#else
+static_assert(alignof(Derived2) == 8, "");
+#endif
+
+struct alignas(16) VBase1 { // itanium-warning {{explicit alignment of VBase1 (16 bytes) was weakened to 4 bytes}}
+  int x;
+};
+
+#pragma pack(4)
+struct VDerived1 : virtual VBase1 {
+  char y;
+};
+#pragma pack()
+VDerived1 vd1;
+
+#ifdef ITANIUM
+static_assert(alignof(VDerived1) == 4, "");
+#else
+static_assert(alignof(VDerived1) == 16, "");
+#endif
+
+struct alignas(4) VBase2 { 
+  int x;
+};
+
+#pragma pack(8)
+struct VDerived2 : virtual VBase2 {
+  char y;
+};
+#pragma pack()
+VDerived2 vd2;
+static_assert(alignof(VDerived2) >= 4, "");

>From 1de3e42870361f5c7336c091c8adfe1e8db7c94e Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Tue, 19 May 2026 08:37:28 -0700
Subject: [PATCH 2/3] Silence unrelated tests

---
 clang/test/Sema/bitfield-layout_1.c        | 10 +++++-----
 clang/test/Sema/pragma-align-packed.c      |  2 +-
 clang/test/Sema/pragma-pack-4.c            |  4 ++--
 clang/test/Sema/test-wunaligned-access.c   |  2 +-
 clang/test/Sema/test-wunaligned-access.cpp |  2 +-
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/test/Sema/bitfield-layout_1.c b/clang/test/Sema/bitfield-layout_1.c
index 3db83c7463503..b3705d3971d6e 100644
--- a/clang/test/Sema/bitfield-layout_1.c
+++ b/clang/test/Sema/bitfield-layout_1.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9  -Wms-bitfield-padding 
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9 -Wno-weakened-alignment
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf -Wno-weakened-alignment
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu -Wno-weakened-alignment
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu -Wno-weakened-alignment
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9  -Wms-bitfield-padding  -Wno-weakened-alignment
 // expected-no-diagnostics
 
 #define CHECK_SIZE(name, size) \
diff --git a/clang/test/Sema/pragma-align-packed.c b/clang/test/Sema/pragma-align-packed.c
index b8daf40b2c829..065e89c7a14e3 100644
--- a/clang/test/Sema/pragma-align-packed.c
+++ b/clang/test/Sema/pragma-align-packed.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s -Wno-weakened-alignment
 // expected-no-diagnostics
 
 #pragma pack(push, 1)
diff --git a/clang/test/Sema/pragma-pack-4.c b/clang/test/Sema/pragma-pack-4.c
index 6b4c2feeb53a2..7896db052e12a 100644
--- a/clang/test/Sema/pragma-pack-4.c
+++ b/clang/test/Sema/pragma-pack-4.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify -Wno-weakened-alignment
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify -Wno-weakened-alignment
 // expected-no-diagnostics
 
 #pragma pack(4)
diff --git a/clang/test/Sema/test-wunaligned-access.c b/clang/test/Sema/test-wunaligned-access.c
index 4680ff4cf19c0..156ec677f9b01 100644
--- a/clang/test/Sema/test-wunaligned-access.c
+++ b/clang/test/Sema/test-wunaligned-access.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -Wno-weakened-alignment -emit-llvm -o %t
 // REQUIRES: arm-registered-target
 //
 // This test suite tests the warning triggered by the -Wunaligned-access option.
diff --git a/clang/test/Sema/test-wunaligned-access.cpp b/clang/test/Sema/test-wunaligned-access.cpp
index a27fd9cba85d5..082dfdbc7539e 100644
--- a/clang/test/Sema/test-wunaligned-access.cpp
+++ b/clang/test/Sema/test-wunaligned-access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -Wno-weakened-alignment -emit-llvm -o %t
 // REQUIRES: arm-registered-target
 //
 // This test suite tests the warning triggered by the -Wunaligned-access option.

>From 7e480d7fcb0cf8f023f41d136ad58773c5eb2703 Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Sat, 6 Jun 2026 15:11:01 -0700
Subject: [PATCH 3/3] Add note indicating location of weakening alignment

---
 clang/docs/ReleaseNotes.rst                   | 13 ++++
 .../include/clang/Basic/DiagnosticASTKinds.td |  8 +-
 clang/include/clang/Basic/DiagnosticGroups.td |  1 -
 clang/lib/AST/RecordLayoutBuilder.cpp         | 73 ++++++++++++++++---
 clang/lib/Sema/SemaAttr.cpp                   |  3 +-
 clang/test/Sema/bitfield-layout_1.c           | 10 +--
 clang/test/Sema/pragma-align-packed.c         |  2 +-
 clang/test/Sema/pragma-pack-4.c               |  4 +-
 clang/test/Sema/test-wunaligned-access.c      |  2 +-
 clang/test/Sema/test-wunaligned-access.cpp    |  2 +-
 .../test/SemaCXX/warn-weakened-alignment.cpp  | 62 ++++++++++++++--
 11 files changed, 146 insertions(+), 34 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5edec5f04e976..0a4530cce747d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -382,6 +382,19 @@ Improvements to Clang's diagnostics
   code can automatically be made portable to other host platforms that don't
   support backslashes.
 
+- Added ``-Wweakened-alignment``, which warns when an explicitly requested
+  alignment (e.g. ``alignas`` or the ``aligned`` attribute) is reduced by
+  another feature such as ``#pragma pack`` or the ``packed`` attribute. An
+  accompanying note points at the feature responsible. This is not emitted
+  under the Microsoft C++ ABI. For example:
+
+  .. code-block:: c++
+
+    #pragma pack(2)      // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
+    struct D1 {
+      char m1;
+      alignas(8) int m4; // itanium-warning {{explicit alignment of m4 (8 bytes) was weakened to 2 bytes}}
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 3a44a12e5a33d..d320c8e2ef555 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -1101,6 +1101,10 @@ def warn_unaligned_access : Warning<
 
 // -Wweakened-alignment
 def warn_explicit_alignment_weakened : Warning<
-  "explicit alignment of %0 (%1 bytes) was weakened to %2 bytes">,
-  InGroup<WeakenedAlignment>;
+  "explicit alignment of %0 (%1 %plural{1:byte|:bytes}1) was weakened to %2 %plural{1:byte|:bytes}2">,
+  InGroup<DiagGroup<"weakened-alignment">>, DefaultIgnore;
+def note_weakened_alignment_source : Note<
+  "%select{'#pragma pack'|the 'packed' attribute|'#pragma options align'|"
+  "the '-fpack-struct' command-line option}0 forces a maximum alignment of "
+  "%1 %plural{1:byte|:bytes}1">;
 }
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 61899587137e4..3136d109e795b 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -845,7 +845,6 @@ def Packed : DiagGroup<"packed", [PackedNonPod]>;
 def PaddedBitField : DiagGroup<"padded-bitfield">;
 def Padded : DiagGroup<"padded", [PaddedBitField]>;
 def UnalignedAccess : DiagGroup<"unaligned-access">;
-def WeakenedAlignment : DiagGroup<"weakened-alignment">;
 def MSBitfieldCompatibility : DiagGroup<"ms-bitfield-padding"> {
   code Documentation = [{
     Under the Microsoft ABI, adjacent bit-fields are not packed if the
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 0ce3752b40961..6c5f010ec18b9 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -680,6 +680,10 @@ class ItaniumRecordLayoutBuilder {
   /// Valid if UseExternalLayout is true.
   ExternalLayout External;
 
+  // Used to locate the feature (#pragma pack or packed attribute) that
+  // weakened an explicit alignment for -Wweakened-alignment.
+  const Decl *RecordBeingLaidOut = nullptr;
+
   ItaniumRecordLayoutBuilder(const ASTContext &Context,
                              EmptySubobjectMap *EmptySubobjects)
       : Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
@@ -817,6 +821,9 @@ class ItaniumRecordLayoutBuilder {
 
   ItaniumRecordLayoutBuilder(const ItaniumRecordLayoutBuilder &) = delete;
   void operator=(const ItaniumRecordLayoutBuilder &) = delete;
+
+  void DiagnoseAlignmentWeakeningSource(const Decl *RD, CharUnits Weakened,
+                                        bool DueToPackedAttr);
 };
 } // end anonymous namespace
 
@@ -1210,15 +1217,16 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
       HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset);
   }
 
+  // Clang <= 6 incorrectly applied the 'packed' attribute to base classes.
+  // Per GCC's documentation, it only applies to non-static data members.
+  const bool PackedAppliesToBases =
+      Packed && ((Context.getLangOpts().getClangABICompat() <=
+                  LangOptions::ClangABI::Ver6) ||
+                 Context.getTargetInfo().getTriple().isPS() ||
+                 Context.getTargetInfo().getTriple().isOSAIX());
+
   auto getBaseOrPreferredBaseAlignFromUnpacked = [&](CharUnits UnpackedAlign) {
-    // Clang <= 6 incorrectly applied the 'packed' attribute to base classes.
-    // Per GCC's documentation, it only applies to non-static data members.
-    return (Packed && ((Context.getLangOpts().getClangABICompat() <=
-                        LangOptions::ClangABI::Ver6) ||
-                       Context.getTargetInfo().getTriple().isPS() ||
-                       Context.getTargetInfo().getTriple().isOSAIX()))
-               ? CharUnits::One()
-               : UnpackedAlign;
+    return PackedAppliesToBases ? CharUnits::One() : UnpackedAlign;
   };
 
   CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlignment();
@@ -1272,8 +1280,11 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
       Context.toCharUnitsFromBits(Base->Class->getMaxAlignment());
   if (!MaxAlignmentInChars.isZero() && MaxAlignmentInChars > BaseAlign) {
     Diag(Base->Class->getLocation(), diag::warn_explicit_alignment_weakened)
-        << Base->Class->getName() << MaxAlignmentInChars.getQuantity()
-        << BaseAlign.getQuantity();
+        << Base->Class
+        << static_cast<unsigned>(MaxAlignmentInChars.getQuantity())
+        << static_cast<unsigned>(BaseAlign.getQuantity());
+    DiagnoseAlignmentWeakeningSource(RecordBeingLaidOut, BaseAlign,
+                                     PackedAppliesToBases);
   }
 
   CharUnits AlignTo =
@@ -1314,6 +1325,7 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
 }
 
 void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) {
+  RecordBeingLaidOut = D;
   if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
     IsUnion = RD->isUnion();
     IsMsStruct = RD->isMsStruct(Context);
@@ -2058,8 +2070,10 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
 
   if (!MaxAlignmentInChars.isZero() && MaxAlignmentInChars > AlignTo) {
     Diag(D->getLocation(), diag::warn_explicit_alignment_weakened)
-        << D->getName() << MaxAlignmentInChars.getQuantity()
-        << AlignTo.getQuantity();
+        << D << static_cast<unsigned>(MaxAlignmentInChars.getQuantity())
+        << static_cast<unsigned>(AlignTo.getQuantity());
+    DiagnoseAlignmentWeakeningSource(RecordBeingLaidOut, AlignTo,
+                                     /*DueToPackedAttr=*/false);
   }
 
   // Round up the current record size to the field's alignment boundary.
@@ -2468,6 +2482,41 @@ static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) {
   llvm_unreachable("bad tail-padding use kind");
 }
 
+void ItaniumRecordLayoutBuilder::DiagnoseAlignmentWeakeningSource(
+    const Decl *RD, CharUnits Weakened, bool DueToPackedAttr) {
+  enum WeakeningSource {
+    WS_PragmaPack,
+    WS_PackedAttr,
+    WS_PragmaOptionsAlign,
+    WS_CommandLine,
+  };
+  WeakeningSource Source;
+  SourceLocation Loc;
+
+  if (DueToPackedAttr) {
+    Source = WS_PackedAttr;
+    if (const auto *PA = RD->getAttr<PackedAttr>())
+      Loc = PA->getLocation();
+  } else if (RD->hasAttr<AlignMac68kAttr>()) {
+    Source = WS_PragmaOptionsAlign;
+    if (const auto *A = RD->getAttr<AlignMac68kAttr>())
+      Loc = A->getLocation();
+  } else if (const auto *MFAA = RD->getAttr<MaxFieldAlignmentAttr>()) {
+    Source = WS_PragmaPack;
+    Loc = MFAA->getLocation();
+  } else {
+    Source = WS_CommandLine;
+  }
+
+  // Fall back to the record location.
+  if (Loc.isInvalid())
+    Loc = RD->getLocation();
+
+  Diag(Loc, diag::note_weakened_alignment_source)
+      << static_cast<unsigned>(Source)
+      << static_cast<unsigned>(Weakened.getQuantity());
+}
+
 // This section contains an implementation of struct layout that is, up to the
 // included tests, compatible with cl.exe (2013).  The layout produced is
 // significantly different than those produced by the Itanium ABI.  Here we note
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 7c79f954e6743..b355244e4f48b 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -67,7 +67,8 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
   } else if (IsPackSet) {
     // Check to see if we need a max field alignment attribute.
     RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(
-        Context, InfoVal.getPackNumber() * 8));
+        Context, InfoVal.getPackNumber() * 8,
+        SourceRange(AlignPackStack.CurrentPragmaLocation)));
   }
 
   if (IsXLPragma && M == AlignPackInfo::Natural)
diff --git a/clang/test/Sema/bitfield-layout_1.c b/clang/test/Sema/bitfield-layout_1.c
index b3705d3971d6e..3db83c7463503 100644
--- a/clang/test/Sema/bitfield-layout_1.c
+++ b/clang/test/Sema/bitfield-layout_1.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9 -Wno-weakened-alignment
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf -Wno-weakened-alignment
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu -Wno-weakened-alignment
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu -Wno-weakened-alignment
-// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9  -Wms-bitfield-padding  -Wno-weakened-alignment
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=i686-apple-darwin9  -Wms-bitfield-padding 
 // expected-no-diagnostics
 
 #define CHECK_SIZE(name, size) \
diff --git a/clang/test/Sema/pragma-align-packed.c b/clang/test/Sema/pragma-align-packed.c
index 065e89c7a14e3..b8daf40b2c829 100644
--- a/clang/test/Sema/pragma-align-packed.c
+++ b/clang/test/Sema/pragma-align-packed.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s -Wno-weakened-alignment
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
 // expected-no-diagnostics
 
 #pragma pack(push, 1)
diff --git a/clang/test/Sema/pragma-pack-4.c b/clang/test/Sema/pragma-pack-4.c
index 7896db052e12a..6b4c2feeb53a2 100644
--- a/clang/test/Sema/pragma-pack-4.c
+++ b/clang/test/Sema/pragma-pack-4.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify -Wno-weakened-alignment
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify -Wno-weakened-alignment
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -verify
 // expected-no-diagnostics
 
 #pragma pack(4)
diff --git a/clang/test/Sema/test-wunaligned-access.c b/clang/test/Sema/test-wunaligned-access.c
index 156ec677f9b01..4680ff4cf19c0 100644
--- a/clang/test/Sema/test-wunaligned-access.c
+++ b/clang/test/Sema/test-wunaligned-access.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -Wno-weakened-alignment -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -emit-llvm -o %t
 // REQUIRES: arm-registered-target
 //
 // This test suite tests the warning triggered by the -Wunaligned-access option.
diff --git a/clang/test/Sema/test-wunaligned-access.cpp b/clang/test/Sema/test-wunaligned-access.cpp
index 082dfdbc7539e..a27fd9cba85d5 100644
--- a/clang/test/Sema/test-wunaligned-access.cpp
+++ b/clang/test/Sema/test-wunaligned-access.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -Wno-weakened-alignment -emit-llvm -o %t
+// RUN: %clang_cc1 %s -triple=armv7-none-none-eabi -verify -Wunaligned-access -emit-llvm -o %t
 // REQUIRES: arm-registered-target
 //
 // This test suite tests the warning triggered by the -Wunaligned-access option.
diff --git a/clang/test/SemaCXX/warn-weakened-alignment.cpp b/clang/test/SemaCXX/warn-weakened-alignment.cpp
index 2ca8e86e9511e..dc07bbb452b77 100644
--- a/clang/test/SemaCXX/warn-weakened-alignment.cpp
+++ b/clang/test/SemaCXX/warn-weakened-alignment.cpp
@@ -3,10 +3,10 @@
 
 // msvc-no-diagnostics
 
-#pragma pack(2)
+#pragma pack(2)      // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
 struct D1 {
   char m1;
-  alignas(8) int m4; // itanium-warning {{explicit alignment of m4 (8 bytes) was weakened to 2 bytes}}
+  alignas(8) int m4; // itanium-warning {{explicit alignment of 'm4' (8 bytes) was weakened to 2 bytes}}
 };
 
 #ifdef ITANIUM
@@ -30,11 +30,11 @@ struct D3 {
 static_assert(alignof(D3) == 4, "");
 #pragma pack()
 
-struct alignas(16) Base1 { // itanium-warning {{explicit alignment of Base1 (16 bytes) was weakened to 2 bytes}}
+struct alignas(16) Base1 { // itanium-warning {{explicit alignment of 'Base1' (16 bytes) was weakened to 2 bytes}}
   int x;
 };
 
-#pragma pack(2)
+#pragma pack(2) // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
 struct Derived1 : Base1 {
   char y;
 };
@@ -47,11 +47,11 @@ static_assert(alignof(Derived1) == 2, "");
 static_assert(alignof(Derived1) == 16, "");
 #endif
 
-struct alignas(8) Base2 { // itanium-warning {{explicit alignment of Base2 (8 bytes) was weakened to 4 bytes}}
+struct alignas(8) Base2 { // itanium-warning {{explicit alignment of 'Base2' (8 bytes) was weakened to 4 bytes}}
   int x;
 };
 
-#pragma pack(4)
+#pragma pack(4) // itanium-note {{'#pragma pack' forces a maximum alignment of 4 bytes}}
 struct Derived2 : Base2 {
   char y;
 };
@@ -64,11 +64,11 @@ static_assert(alignof(Derived2) == 4, "");
 static_assert(alignof(Derived2) == 8, "");
 #endif
 
-struct alignas(16) VBase1 { // itanium-warning {{explicit alignment of VBase1 (16 bytes) was weakened to 4 bytes}}
+struct alignas(16) VBase1 { // itanium-warning {{explicit alignment of 'VBase1' (16 bytes) was weakened to 4 bytes}}
   int x;
 };
 
-#pragma pack(4)
+#pragma pack(4) // itanium-note {{'#pragma pack' forces a maximum alignment of 4 bytes}}
 struct VDerived1 : virtual VBase1 {
   char y;
 };
@@ -92,3 +92,49 @@ struct VDerived2 : virtual VBase2 {
 #pragma pack()
 VDerived2 vd2;
 static_assert(alignof(VDerived2) >= 4, "");
+
+#pragma pack(2)       // itanium-note 2 {{'#pragma pack' forces a maximum alignment of 2 bytes}}
+struct M1 {
+  alignas(8) int a;   // itanium-warning {{explicit alignment of 'a' (8 bytes) was weakened to 2 bytes}}
+  alignas(16) long b; // itanium-warning {{explicit alignment of 'b' (16 bytes) was weakened to 2 bytes}}
+};
+#pragma pack()
+#ifdef ITANIUM
+static_assert(alignof(M1) == 2, "");
+#else
+static_assert(alignof(M1) == 16, "");
+#endif
+
+#pragma pack(push, 2) // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
+struct P1 {
+  alignas(8) int m;   // itanium-warning {{explicit alignment of 'm' (8 bytes) was weakened to 2 bytes}}
+};
+#pragma pack(pop)
+#ifdef ITANIUM
+static_assert(alignof(P1) == 2, "");
+#else
+static_assert(alignof(P1) == 8, "");
+#endif
+
+#pragma pack(2) // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
+struct G1 {
+  int m __attribute__((aligned(8))); // itanium-warning {{explicit alignment of 'm' (8 bytes) was weakened to 2 bytes}}
+};
+#pragma pack()
+#ifdef ITANIUM
+static_assert(alignof(G1) == 2, "");
+#else
+static_assert(alignof(G1) == 8, "");
+#endif
+
+#pragma pack(2)     // itanium-note {{'#pragma pack' forces a maximum alignment of 2 bytes}}
+union U1 {
+  char c;
+  alignas(8) int i; // itanium-warning {{explicit alignment of 'i' (8 bytes) was weakened to 2 bytes}}
+};
+#pragma pack()
+#ifdef ITANIUM
+static_assert(alignof(U1) == 2, "");
+#else
+static_assert(alignof(U1) == 8, "");
+#endif



More information about the cfe-commits mailing list