mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 17:46:06 +00:00
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
This commit is contained in:
parent
971d982bd4
commit
a8b0c6fa28
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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*,
|
||||
|
@ -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];
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user