Skip to content

Commit 91d85e2

Browse files
committed
Massage polymorphism check for standard_layout
to deconflict it and make it coherent with existing tablegen diagnostics.
1 parent 2ef836c commit 91d85e2

File tree

3 files changed

+19
-9
lines changed

3 files changed

+19
-9
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,6 @@ def note_unsatisfied_trait_reason
17971797
"%MixedAccess{has mixed access specifiers}|"
17981798
"%MixedAccessField{field %1 has a different access specifier than field %2}|"
17991799
"%MultipleDataBase{has multiple base classes with data members}|"
1800-
"%VirtualFunction{has a virtual function}|"
18011800
"%NonStandardLayoutMember{has a non-standard-layout member %1 of type %2}|"
18021801
"%IndirectBaseWithFields{has an indirect base %1 with data members}|"
18031802
"%DeletedDtr{has a %select{deleted|user-provided}1 destructor}|"

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,15 +2453,26 @@ static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
24532453
<< diag::TraitNotSatisfiedReason::MultipleDataBase;
24542454
}
24552455
if (D->isPolymorphic()) {
2456-
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2457-
<< diag::TraitNotSatisfiedReason::VirtualFunction;
2458-
2459-
for (const CXXMethodDecl *Method : D->methods()) {
2460-
if (Method->isVirtual()) {
2461-
SemaRef.Diag(Method->getLocation(), diag::note_defined_here) << Method;
2456+
// Find the best location to point “defined here” at.
2457+
const CXXMethodDecl *VirtualMD = nullptr;
2458+
// First, look for a virtual method.
2459+
for (const auto *M : D->methods()) {
2460+
if (M->isVirtual()) {
2461+
VirtualMD = M;
24622462
break;
24632463
}
24642464
}
2465+
if (VirtualMD) {
2466+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2467+
<< diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2468+
SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2469+
<< VirtualMD;
2470+
} else {
2471+
// If no virtual method, point to the record declaration itself.
2472+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2473+
<< diag::TraitNotSatisfiedReason::VirtualFunction << D;
2474+
SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2475+
}
24652476
}
24662477
for (const FieldDecl *Field : D->fields()) {
24672478
if (!Field->getType()->isStandardLayoutType()) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ struct WithVirtual { // #sl-Virtual
642642
static_assert(__is_standard_layout(WithVirtual));
643643
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::WithVirtual)'}} \
644644
// expected-note@-1 {{'WithVirtual' is not standard-layout}} \
645-
// expected-note@-1 {{because it has a virtual function}} \
645+
// expected-note@-1 {{because it has a virtual function 'foo'}} \
646646
// expected-note@#sl-Virtual-Foo {{'foo' defined here}} \
647647
// expected-note@#sl-Virtual {{'WithVirtual' defined here}}
648648

@@ -667,7 +667,7 @@ static_assert(__is_standard_layout(VB));
667667
// expected-note@-1 {{'VB' is not standard-layout}} \
668668
// expected-note@-1 {{because it has a virtual base 'VirtualBase'}} \
669669
// expected-note@-1 {{because it has a non-standard-layout base 'VirtualBase'}} \
670-
// expected-note@-1 {{because it has a virtual function}}
670+
// expected-note@-1 {{because it has a virtual function '~VB'}} \
671671
// expected-note@#sl-VB {{'VB' defined here}}
672672
// expected-note@#sl-VB {{'~VB' defined here}}
673673

0 commit comments

Comments
 (0)