[clang] [clang] Separate bit-field padding diagnostics into -Wpadded-bitfield (PR #70978)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 1 14:54:37 PDT 2023
https://github.com/DanShaders updated https://github.com/llvm/llvm-project/pull/70978
>From 5446542556971dfcfed097ad92925712cbe3a7a8 Mon Sep 17 00:00:00 2001
From: Dan Klishch <danilklishch at gmail.com>
Date: Wed, 1 Nov 2023 15:31:49 -0400
Subject: [PATCH 1/2] [clang] Separate bit-field padding diagnostics into
-Wpadded-bitfield
---
.../include/clang/Basic/DiagnosticASTKinds.td | 14 ++++++---
clang/include/clang/Basic/DiagnosticGroups.td | 3 +-
clang/lib/AST/RecordLayoutBuilder.cpp | 20 ++++++++-----
.../warn-all-padded-packed-packed-non-pod.cpp | 4 +--
.../test/CodeGenCXX/warn-padded-bitfields.cpp | 29 +++++++++++++++++++
5 files changed, 55 insertions(+), 15 deletions(-)
create mode 100644 clang/test/CodeGenCXX/warn-padded-bitfields.cpp
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 031117f2c4137a4..94d1907bce6d044 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -998,14 +998,20 @@ def warn_npot_ms_struct : Warning<
"data types with sizes that aren't a power of two">,
DefaultError, InGroup<IncompatibleMSStruct>;
-// -Wpadded, -Wpacked
-def warn_padded_struct_field : Warning<
+// -Wpadded-bitfield
+def warn_padded_struct_bitfield : Warning<
"padding %select{struct|interface|class}0 %1 with %2 "
"%select{byte|bit}3%s2 to align %4">,
- InGroup<Padded>, DefaultIgnore;
-def warn_padded_struct_anon_field : Warning<
+ InGroup<PaddedBitField>, DefaultIgnore;
+def warn_padded_struct_anon_bitfield : Warning<
"padding %select{struct|interface|class}0 %1 with %2 "
"%select{byte|bit}3%s2 to align anonymous bit-field">,
+ InGroup<PaddedBitField>, DefaultIgnore;
+
+// -Wpadded, -Wpacked
+def warn_padded_struct_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align %4">,
InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_size : Warning<
"padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 9a8f3f03b39d165..bfda89945d635bd 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -586,7 +586,8 @@ def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
def OrderedCompareFunctionPointers : DiagGroup<"ordered-compare-function-pointers">;
def PackedNonPod : DiagGroup<"packed-non-pod">;
def Packed : DiagGroup<"packed", [PackedNonPod]>;
-def Padded : DiagGroup<"padded">;
+def PaddedBitField : DiagGroup<"padded-bitfield">;
+def Padded : DiagGroup<"padded", [PaddedBitField]>;
def UnalignedAccess : DiagGroup<"unaligned-access">;
def PessimizingMove : DiagGroup<"pessimizing-move">;
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f1f2275da44dcad..982266488d488e2 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2297,19 +2297,23 @@ void ItaniumRecordLayoutBuilder::CheckFieldPadding(
PadSize = PadSize / CharBitNum;
InBits = false;
}
- if (D->getIdentifier())
- Diag(D->getLocation(), diag::warn_padded_struct_field)
+ if (D->getIdentifier()) {
+ auto Diagnostic = D->isBitField() ? diag::warn_padded_struct_bitfield
+ : diag::warn_padded_struct_field;
+ Diag(D->getLocation(), Diagnostic)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
- << Context.getTypeDeclType(D->getParent())
- << PadSize
+ << Context.getTypeDeclType(D->getParent()) << PadSize
<< (InBits ? 1 : 0) // (byte|bit)
<< D->getIdentifier();
- else
- Diag(D->getLocation(), diag::warn_padded_struct_anon_field)
+ } else {
+ assert(
+ D->isBitField() &&
+ "Introduced padding for an anonymous field which is not a bit-field");
+ Diag(D->getLocation(), diag::warn_padded_struct_anon_bitfield)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
- << Context.getTypeDeclType(D->getParent())
- << PadSize
+ << Context.getTypeDeclType(D->getParent()) << PadSize
<< (InBits ? 1 : 0); // (byte|bit)
+ }
}
if (isPacked && Offset != UnpackedOffset) {
HasPackedField = true;
diff --git a/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp b/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
index 2a75498d87197a4..5e166deba0a3f05 100644
--- a/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
+++ b/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
@@ -1,5 +1,5 @@
-// 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
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -Wno-padded-bitfield -verify=expected,top %s -emit-llvm-only
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded -Wpacked -Wno-padded-bitfield -verify=expected,abi15 -fclang-abi-compat=15 %s -emit-llvm-only
// -Wpacked-non-pod itself should not emit the "packed attribute is unnecessary" warnings.
// RUN: %clang_cc1 -triple=x86_64-none-none -Wpacked-non-pod -verify=top %s -emit-llvm-only
// -Wall should not emit the "packed attribute is unnecessary" warnings without -Wpacked.
diff --git a/clang/test/CodeGenCXX/warn-padded-bitfields.cpp b/clang/test/CodeGenCXX/warn-padded-bitfields.cpp
new file mode 100644
index 000000000000000..1206346ebfbc2c2
--- /dev/null
+++ b/clang/test/CodeGenCXX/warn-padded-bitfields.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple=x86_64-none-none -Wpadded-bitfield -verify=expected %s -emit-llvm-only
+
+struct S1 {
+ unsigned a : 1;
+ unsigned long long : 0; // expected-warning {{padding struct 'S1' with 63 bits to align anonymous bit-field}}
+};
+
+struct S2 {
+ unsigned a : 1;
+ unsigned long long b : 64; // expected-warning {{padding struct 'S2' with 63 bits to align 'b'}}
+};
+
+struct S3 {
+ char a : 1;
+ short b : 16; // expected-warning {{padding struct 'S3' with 15 bits to align 'b'}}
+};
+
+struct [[gnu::packed]] S4 {
+ char a : 1;
+ short b : 16;
+};
+
+struct S5 {
+ unsigned a : 1;
+ unsigned long long b : 63;
+};
+
+// 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){}
>From e3715d277860b6c972237463a5f2628f0877b7ea Mon Sep 17 00:00:00 2001
From: Dan Klishch <danilklishch at gmail.com>
Date: Wed, 1 Nov 2023 17:54:22 -0400
Subject: [PATCH 2/2] fixup
---
clang/include/clang/Basic/DiagnosticASTKinds.td | 4 ++++
clang/lib/AST/RecordLayoutBuilder.cpp | 7 +++----
clang/test/CodeGenCXX/warn-padded-bitfields.cpp | 14 +++++++++++++-
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td
index 94d1907bce6d044..c81d17ed641084a 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.td
+++ b/clang/include/clang/Basic/DiagnosticASTKinds.td
@@ -1013,6 +1013,10 @@ def warn_padded_struct_field : Warning<
"padding %select{struct|interface|class}0 %1 with %2 "
"%select{byte|bit}3%s2 to align %4">,
InGroup<Padded>, DefaultIgnore;
+def warn_padded_struct_anon_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%s2 to align anonymous field">,
+ InGroup<Padded>, DefaultIgnore;
def warn_padded_struct_size : Warning<
"padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">,
InGroup<Padded>, DefaultIgnore;
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 982266488d488e2..5d4f930fca50e2b 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2306,10 +2306,9 @@ void ItaniumRecordLayoutBuilder::CheckFieldPadding(
<< (InBits ? 1 : 0) // (byte|bit)
<< D->getIdentifier();
} else {
- assert(
- D->isBitField() &&
- "Introduced padding for an anonymous field which is not a bit-field");
- Diag(D->getLocation(), diag::warn_padded_struct_anon_bitfield)
+ auto Diagnostic = D->isBitField() ? diag::warn_padded_struct_anon_bitfield
+ : diag::warn_padded_struct_anon_field;
+ Diag(D->getLocation(), Diagnostic)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
<< Context.getTypeDeclType(D->getParent()) << PadSize
<< (InBits ? 1 : 0); // (byte|bit)
diff --git a/clang/test/CodeGenCXX/warn-padded-bitfields.cpp b/clang/test/CodeGenCXX/warn-padded-bitfields.cpp
index 1206346ebfbc2c2..f9882d03564fe6e 100644
--- a/clang/test/CodeGenCXX/warn-padded-bitfields.cpp
+++ b/clang/test/CodeGenCXX/warn-padded-bitfields.cpp
@@ -25,5 +25,17 @@ struct S5 {
unsigned long long b : 63;
};
+struct S6 {
+ unsigned a : 1;
+ unsigned long long b;
+};
+
+struct S7 {
+ int word;
+ struct {
+ int filler __attribute__ ((aligned (8)));
+ };
+};
+
// 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){}
+void f(S1, S2, S3, S4, S5, S6, S7){}
More information about the cfe-commits
mailing list