[clang] a8b0c6f - Remove -Wpacked false positive for non-pod types where the layout isn't directly changed

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Mon May 8 17:15:13 PDT 2023


Author: David Blaikie
Date: 2023-05-09T00:13:45Z
New Revision: a8b0c6fa28acced71db33e80bd0b51d00422035b

URL: https://github.com/llvm/llvm-project/commit/a8b0c6fa28acced71db33e80bd0b51d00422035b
DIFF: https://github.com/llvm/llvm-project/commit/a8b0c6fa28acced71db33e80bd0b51d00422035b.diff

LOG: Remove -Wpacked false positive for non-pod types where the layout isn't directly changed

The packed attribute can still be useful in this case if the struct is
then placed inside another packed struct - the non-pod element type's
packed attribute declares that it's OK to misalign this element inside
the packed structure. (otherwise the non-pod element is not packed/its
alignment is preserved, as per D117616/2771233)

Fixes PR62353

Differential Revision: https://reviews.llvm.org/D149182

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/RecordLayoutBuilder.cpp
    clang/test/CodeGenCXX/warn-padded-packed.cpp
    clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4f8165bbc8ee5..aa9a8a60e586d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -111,6 +111,12 @@ Resolutions to C++ Defect Reports
 - Implemented `DR2397 <https://wg21.link/CWG2397>`_ which allows ``auto`` specifier for pointers
   and reference to arrays.
 
+Warnings
+^^^^^^^^
+- Address a false positive in ``-Wpacked`` when applied to a non-pod type using
+  Clang ABI >= 15 (fixes `#62353<https://github.com/llvm/llvm-project/issues/62353>`_,
+  fallout from the non-POD packing ABI fix in LLVM 15)
+
 C Language Changes
 ------------------
 - Support for outputs from asm goto statements along indirect edges has been

diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 641e9d62149e9..aca50912dceac 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2198,11 +2198,19 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
           << (InBits ? 1 : 0); // (byte|bit)
     }
 
+    const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
+
     // Warn if we packed it unnecessarily, when the unpacked alignment is not
     // greater than the one after packing, the size in bits doesn't change and
     // the offset of each field is identical.
+    // Unless the type is non-POD (for Clang ABI > 15), where the packed
+    // attribute on such a type does allow the type to be packed into other
+    // structures that use the packed attribute.
     if (Packed && UnpackedAlignment <= Alignment &&
-        UnpackedSizeInBits == getSizeInBits() && !HasPackedField)
+        UnpackedSizeInBits == getSizeInBits() && !HasPackedField &&
+        (!CXXRD || CXXRD->isPOD() ||
+         Context.getLangOpts().getClangABICompat() <=
+             LangOptions::ClangABI::Ver15))
       Diag(D->getLocation(), diag::warn_unnecessary_packed)
           << Context.getTypeDeclType(RD);
   }

diff  --git a/clang/test/CodeGenCXX/warn-padded-packed.cpp b/clang/test/CodeGenCXX/warn-padded-packed.cpp
index cf4890e40005d..c51a6c9443f6e 100644
--- a/clang/test/CodeGenCXX/warn-padded-packed.cpp
+++ b/clang/test/CodeGenCXX/warn-padded-packed.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify %s -emit-llvm-only
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify=expected,top %s -emit-llvm-only
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -verify=expected,abi15 -fclang-abi-compat=15 %s -emit-llvm-only
 
 struct S1 {
   char c;
@@ -154,7 +155,7 @@ struct S28 {
   char c1;
   short s1;
   char c2;
-  S28_non_pod p1; // expected-warning {{not packing field 'p1' as it is non-POD for the purposes of layout}}
+  S28_non_pod p1; // top-warning {{not packing field 'p1' as it is non-POD for the purposes of layout}}
 } __attribute__((packed));
 
 struct S29_non_pod_align_1 {
@@ -167,6 +168,16 @@ struct S29 {
 } __attribute__((packed)); // no warning
 static_assert(alignof(S29) == 1, "");
 
+struct S30 {
+protected:
+ short s;
+} __attribute__((packed)); // no warning
+struct S30_use { // abi15-warning {{packed attribute is unnecessary for 'S30_use'}}
+  char c;
+  S30 u;
+} __attribute__((packed));
+static_assert(sizeof(S30_use) == 3, "");
+
 // The warnings are emitted when the layout of the structs is computed, so we have to use them.
 void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*,
        S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,

diff  --git a/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp b/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
index 37982fcb74b96..1576b8561cb56 100644
--- a/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
+++ b/clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
@@ -6,6 +6,8 @@
 // RUN:     -fdump-record-layouts -fsyntax-only -verify -x c++ < %s | \
 // RUN:   FileCheck %s
 
+// expected-no-diagnostics
+
 struct A {
   double d;
 };
@@ -14,7 +16,7 @@ struct B {
   char x[8];
 };
 
-struct [[gnu::packed]] C : B, A { // expected-warning{{packed attribute is unnecessary for 'C'}}
+struct [[gnu::packed]] C : B, A {
   char x alignas(4)[8];
 };
 


        


More information about the cfe-commits mailing list