Skip to content

Commit b128769

Browse files
committed
Address PR comments
Add info about diagnostic in ReleaseNotes.rst
1 parent c56a2af commit b128769

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
@@ -2289,32 +2289,38 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
22892289
static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc,
22902290
const CXXRecordDecl *D) {
22912291
// Non-static data members (ignore zero-width bit‐fields).
2292-
for (auto *Field : D->fields()) {
2293-
if (Field->isBitField() && Field->getBitWidthValue() == 0)
2292+
for (const auto *Field : D->fields()) {
2293+
if (Field->isZeroLengthBitField())
22942294
continue;
2295+
if (Field->isBitField()) {
2296+
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2297+
<< diag::TraitNotSatisfiedReason::ZeroLengthField << Field
2298+
<< Field->getSourceRange();
2299+
continue;
2300+
}
22952301
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
22962302
<< diag::TraitNotSatisfiedReason::NonEmptyMember << Field
22972303
<< Field->getType() << Field->getSourceRange();
22982304
}
22992305

23002306
// Virtual functions.
2301-
for (auto *M : D->methods()) {
2307+
for (const auto *M : D->methods()) {
23022308
if (M->isVirtual()) {
23032309
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2304-
<< diag::TraitNotSatisfiedReason::VirtualFunction << M->getDeclName()
2310+
<< diag::TraitNotSatisfiedReason::VirtualFunction << M
23052311
<< M->getSourceRange();
23062312
break;
23072313
}
23082314
}
23092315

23102316
// Virtual bases and non-empty bases.
2311-
for (auto &B : D->bases()) {
2312-
auto *BR = B.getType()->getAsCXXRecordDecl();
2317+
for (const auto &B : D->bases()) {
2318+
const auto *BR = B.getType()->getAsCXXRecordDecl();
23132319
if (!BR || BR->isInvalidDecl())
23142320
continue;
23152321
if (B.isVirtual()) {
23162322
S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2317-
<< diag::TraitNotSatisfiedReason::VirtualBase << B.getType()
2323+
<< diag::TraitNotSatisfiedReason::VBase << B.getType()
23182324
<< B.getSourceRange();
23192325
}
23202326
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
@@ -520,7 +520,7 @@ namespace is_empty_tests {
520520
static_assert(__is_empty(VB));
521521
// expected-error@-1 {{static assertion failed due to requirement '__is_empty(is_empty_tests::VB)'}} \
522522
// expected-note@-1 {{'VB' is not empty}} \
523-
// expected-note@-1 {{because it has a virtual base class 'EB'}} \
523+
// expected-note@-1 {{because it has a virtual base 'EB'}} \
524524
// expected-note@#e-VB {{'VB' defined here}}
525525

526526
// Non-empty base class.
@@ -543,6 +543,23 @@ namespace is_empty_tests {
543543
// expected-note@-1 {{because it has a non-static data member 'z' of type 'int'}} \
544544
// expected-note@-1 {{because it has a virtual function 'g'}} \
545545
// expected-note@-1 {{because it has a base class 'Base' that is not empty}} \
546-
// expected-note@-1 {{because it has a virtual base class 'EB'}} \
546+
// expected-note@-1 {{because it has a virtual base 'EB'}} \
547547
// expected-note@#e-Multi {{'Multi' defined here}}
548+
549+
// Zero-width bit-field.
550+
struct BitField { int : 0; }; // #e-BitField
551+
static_assert(__is_empty(BitField)); // no diagnostics
552+
553+
// Dependent bit-field width.
554+
template <int N>
555+
struct DependentBitField { int : N; }; // #e-DependentBitField
556+
557+
static_assert(__is_empty(DependentBitField<0>)); // no diagnostics
558+
559+
static_assert(__is_empty(DependentBitField<2>));
560+
// expected-error@-1 {{static assertion failed due to requirement '__is_empty(is_empty_tests::DependentBitField<2>)'}} \
561+
// expected-note@-1 {{'DependentBitField<2>' is not empty}} \
562+
// expected-note@-1 {{because it field '' is a non-zero-length bit-field}} \
563+
// expected-note@#e-DependentBitField {{'DependentBitField<2>' defined here}}
564+
548565
}

0 commit comments

Comments
 (0)