Skip to content

Commit aecedc9

Browse files
committed
Address PR comments
Add info about diagnostic in ReleaseNotes.rst
1 parent 29de582 commit aecedc9

File tree

4 files changed

+36
-10
lines changed

4 files changed

+36
-10
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,10 @@ Improvements to Clang's diagnostics
644644
#GH69470, #GH59391, #GH58172, #GH46215, #GH45915, #GH45891, #GH44490,
645645
#GH36703, #GH32903, #GH23312, #GH69874.
646646

647+
- Clang now gives pinpointed diagnostics for std::is_empty<T> failures—emitting a “not empty” error
648+
plus “because…” notes for non-static members, virtual functions/bases, non-empty bases, and non-zero bit-fields
649+
(including dependent widths) while correctly ignoring zero-width bit-fields.
650+
647651

648652
Improvements to Clang's time-trace
649653
----------------------------------

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,6 @@ def note_unsatisfied_trait_reason
17901790
"%NTCField{has a non-trivially-copyable member %1 of type %2}|"
17911791
"%NonEmptyMember{has a non-static data member %1 of type %2}|"
17921792
"%VirtualFunction{has a virtual function %1}|"
1793-
"%VirtualBase{has a virtual base class %1}|"
17941793
"%NonEmptyBase{has a base class %1 that is not empty}|"
17951794
"%ZeroLengthField{field %1 is a non-zero-length bit-field}|"
17961795
"%DeletedDtr{has a %select{deleted|user-provided}1 destructor}|"

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,32 +2317,38 @@ static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc,
23172317
static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc,
23182318
const CXXRecordDecl *D) {
23192319
// Non-static data members (ignore zero-width bit‐fields).
2320-
for (auto *Field : D->fields()) {
2321-
if (Field->isBitField() && Field->getBitWidthValue() == 0)
2320+
for (const auto *Field : D->fields()) {
2321+
if (Field->isZeroLengthBitField())
23222322
continue;
2323+
if (Field->isBitField()) {
2324+
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2325+
<< diag::TraitNotSatisfiedReason::ZeroLengthField << Field
2326+
<< Field->getSourceRange();
2327+
continue;
2328+
}
23232329
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
23242330
<< diag::TraitNotSatisfiedReason::NonEmptyMember << Field
23252331
<< Field->getType() << Field->getSourceRange();
23262332
}
23272333

23282334
// Virtual functions.
2329-
for (auto *M : D->methods()) {
2335+
for (const auto *M : D->methods()) {
23302336
if (M->isVirtual()) {
23312337
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2332-
<< diag::TraitNotSatisfiedReason::VirtualFunction << M->getDeclName()
2338+
<< diag::TraitNotSatisfiedReason::VirtualFunction << M
23332339
<< M->getSourceRange();
23342340
break;
23352341
}
23362342
}
23372343

23382344
// Virtual bases and non-empty bases.
2339-
for (auto &B : D->bases()) {
2340-
auto *BR = B.getType()->getAsCXXRecordDecl();
2345+
for (const auto &B : D->bases()) {
2346+
const auto *BR = B.getType()->getAsCXXRecordDecl();
23412347
if (!BR || BR->isInvalidDecl())
23422348
continue;
23432349
if (B.isVirtual()) {
23442350
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2345-
<< diag::TraitNotSatisfiedReason::VirtualBase << B.getType()
2351+
<< diag::TraitNotSatisfiedReason::VBase << B.getType()
23462352
<< B.getSourceRange();
23472353
}
23482354
if (!BR->isEmpty()) {

clang/test/SemaCXX/type-traits-unsatisfied-diags.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ namespace is_empty_tests {
591591
static_assert(__is_empty(VB));
592592
// expected-error@-1 {{static assertion failed due to requirement '__is_empty(is_empty_tests::VB)'}} \
593593
// expected-note@-1 {{'VB' is not empty}} \
594-
// expected-note@-1 {{because it has a virtual base class 'EB'}} \
594+
// expected-note@-1 {{because it has a virtual base 'EB'}} \
595595
// expected-note@#e-VB {{'VB' defined here}}
596596

597597
// Non-empty base class.
@@ -614,6 +614,23 @@ namespace is_empty_tests {
614614
// expected-note@-1 {{because it has a non-static data member 'z' of type 'int'}} \
615615
// expected-note@-1 {{because it has a virtual function 'g'}} \
616616
// expected-note@-1 {{because it has a base class 'Base' that is not empty}} \
617-
// expected-note@-1 {{because it has a virtual base class 'EB'}} \
617+
// expected-note@-1 {{because it has a virtual base 'EB'}} \
618618
// expected-note@#e-Multi {{'Multi' defined here}}
619+
620+
// Zero-width bit-field.
621+
struct BitField { int : 0; }; // #e-BitField
622+
static_assert(__is_empty(BitField)); // no diagnostics
623+
624+
// Dependent bit-field width.
625+
template <int N>
626+
struct DependentBitField { int : N; }; // #e-DependentBitField
627+
628+
static_assert(__is_empty(DependentBitField<0>)); // no diagnostics
629+
630+
static_assert(__is_empty(DependentBitField<2>));
631+
// expected-error@-1 {{static assertion failed due to requirement '__is_empty(is_empty_tests::DependentBitField<2>)'}} \
632+
// expected-note@-1 {{'DependentBitField<2>' is not empty}} \
633+
// expected-note@-1 {{because it field '' is a non-zero-length bit-field}} \
634+
// expected-note@#e-DependentBitField {{'DependentBitField<2>' defined here}}
635+
619636
}

0 commit comments

Comments
 (0)