Skip to content

Commit 952535f

Browse files
committed
MixedAccess specifier diagnostics improvement
Diagnose fields which have different access
1 parent 8aa95e2 commit 952535f

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ def note_unsatisfied_trait_reason
17901790
"%NTCField{has a non-trivially-copyable member %1 of type %2}|"
17911791
"%NonStdLayoutBase{has a non-standard-layout base %1}|"
17921792
"%MixedAccess{has mixed access specifiers}|"
1793+
"%MixedAccessField{field %1 has a different access specifier than field %2}|"
17931794
"%MultipleDataBase{has multiple base classes with data members}|"
17941795
"%VirtualFunction{has a virtual function}|"
17951796
"%NonStdLayoutMember{has a non-standard-layout member %1 of type %2}|"

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,27 @@ static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
23372337
if (hasMixedAccessSpecifier(D)) {
23382338
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
23392339
<< diag::TraitNotSatisfiedReason::MixedAccess;
2340+
2341+
const FieldDecl *FirstField = nullptr;
2342+
AccessSpecifier FirstAcc = AS_none;
2343+
for (const FieldDecl *F : D->fields()) {
2344+
if (F->isUnnamedBitField())
2345+
continue;
2346+
if (FirstField == nullptr) {
2347+
FirstField = F;
2348+
FirstAcc = F->getAccess();
2349+
} else if (F->getAccess() != FirstAcc) {
2350+
SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2351+
<< FirstField;
2352+
2353+
SemaRef.Diag(F->getLocation(), diag::note_unsatisfied_trait_reason)
2354+
<< diag::TraitNotSatisfiedReason::MixedAccessField
2355+
<< F // %0: second field
2356+
<< FirstField; // %1: first field
2357+
break;
2358+
}
2359+
}
2360+
return;
23402361
}
23412362
if (hasMultipleDataBaseClassesWithFields(D)) {
23422363
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,14 +502,16 @@ static_assert(__is_standard_layout(WithVirtual));
502502

503503
struct MixedAccess { // #sl-Mixed
504504
public:
505-
int a;
505+
int a; // #sl-MixedF1
506506
private:
507-
int b;
507+
int b; // #sl-MixedF2
508508
};
509509
static_assert(__is_standard_layout(MixedAccess));
510510
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::MixedAccess)'}} \
511511
// expected-note@-1 {{'MixedAccess' is not standard-layout}} \
512512
// expected-note@-1 {{because it has mixed access specifiers}} \
513+
// expected-note@#sl-MixedF1 {{'a' defined here}}
514+
// expected-note@#sl-MixedF2 {{field 'b' has a different access specifier than field 'a'}}
513515
// expected-note@#sl-Mixed {{'MixedAccess' defined here}}
514516

515517
struct VirtualBase { virtual ~VirtualBase(); }; // #sl-VirtualBase
@@ -525,14 +527,16 @@ static_assert(__is_standard_layout(VB));
525527

526528
union U { // #sl-U
527529
public:
528-
int x;
530+
int x; // #sl-UF1
529531
private:
530-
int y;
532+
int y; // #sl-UF2
531533
};
532534
static_assert(__is_standard_layout(U));
533535
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::U)'}} \
534536
// expected-note@-1 {{'U' is not standard-layout}} \
535537
// expected-note@-1 {{because it has mixed access specifiers}}
538+
// expected-note@#sl-UF1 {{'x' defined here}}
539+
// expected-note@#sl-UF2 {{field 'y' has a different access specifier than field 'x'}}
536540
// expected-note@#sl-U {{'U' defined here}}
537541

538542
// Single base class is OK

0 commit comments

Comments
 (0)