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 <danilklis...@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 <danilklis...@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){} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits