Skip to content

Commit 1de5966

Browse files
committed
Remove misleading comment
1 parent 952535f commit 1de5966

File tree

2 files changed

+90
-39
lines changed

2 files changed

+90
-39
lines changed

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2286,21 +2286,6 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
22862286
SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
22872287
}
22882288

2289-
static bool hasMixedAccessSpecifier(const CXXRecordDecl *D) {
2290-
AccessSpecifier FirstAccess = AS_none;
2291-
for (const FieldDecl *Field : D->fields()) {
2292-
2293-
if (Field->isUnnamedBitField())
2294-
continue;
2295-
AccessSpecifier FieldAccess = Field->getAccess();
2296-
if (FirstAccess == AS_none)
2297-
FirstAccess = FieldAccess;
2298-
else if (FieldAccess != FirstAccess)
2299-
return true;
2300-
}
2301-
return false;
2302-
}
2303-
23042289
static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D) {
23052290
int NumBasesWithFields = 0;
23062291
for (const CXXBaseSpecifier &Base : D->bases()) {
@@ -2334,30 +2319,37 @@ static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
23342319
<< B.getSourceRange();
23352320
}
23362321
}
2337-
if (hasMixedAccessSpecifier(D)) {
2338-
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2339-
<< diag::TraitNotSatisfiedReason::MixedAccess;
2322+
// Check for mixed access specifiers in fields.
2323+
const FieldDecl *FirstField = nullptr;
2324+
AccessSpecifier FirstAccess = AS_none;
23402325

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-
}
2326+
for (const FieldDecl *Field : D->fields()) {
2327+
if (Field->isUnnamedBitField())
2328+
continue;
2329+
2330+
// Record the first field we see
2331+
if (!FirstField) {
2332+
FirstField = Field;
2333+
FirstAccess = Field->getAccess();
2334+
continue;
2335+
}
2336+
2337+
// Check if the field has a different access specifier than the first one.
2338+
if (Field->getAccess() != FirstAccess) {
2339+
// Emit a diagnostic about mixed access specifiers.
2340+
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2341+
<< diag::TraitNotSatisfiedReason::MixedAccess;
2342+
2343+
SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2344+
<< FirstField;
2345+
2346+
SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2347+
<< diag::TraitNotSatisfiedReason::MixedAccessField << Field
2348+
<< FirstField;
2349+
2350+
// No need to check further fields, as we already found mixed access.
2351+
return;
23592352
}
2360-
return;
23612353
}
23622354
if (hasMultipleDataBaseClassesWithFields(D)) {
23632355
SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)

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

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-vla-cxx-extension -Wno-c++26-extensions -std=c++20 %s
1+
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-vla-cxx-extension -Wno-c++26-extensions -std=c++20 -fms-extensions %s
22

33
struct S : A {}; // expected-error{{expected class name}}
44

@@ -573,4 +573,63 @@ struct BaseY {}; // #sl-BaseY
573573
struct MultiBase : BaseX, BaseY {}; // #sl-MultiBase
574574
static_assert(__is_standard_layout(MultiBase));
575575

576-
}
576+
struct A {
577+
int x;
578+
};
579+
580+
struct B : A {
581+
};
582+
// Indirect base with data members
583+
struct C : B { int y; }; // #sl-C
584+
static_assert(__is_standard_layout(C));
585+
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::C)'}} \
586+
// expected-note@-1 {{'C' is not standard-layout}} \
587+
// expected-note@-1 {{because it has an indirect base 'A' with data members}} \
588+
// expected-note@#sl-C {{'C' defined here}}
589+
590+
struct D {
591+
union { int a; float b; };
592+
}; // #sl-D
593+
static_assert(__is_standard_layout(D)); // no diagnostics
594+
595+
// E inherits D but adds a new member
596+
struct E : D { int x; }; // #sl-E
597+
static_assert(__is_standard_layout(E));
598+
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::E)'}} \
599+
// expected-note@-1 {{'E' is not standard-layout}} \
600+
// expected-note@-1 {{because it has an indirect base 'D' with data members}} \
601+
// expected-note@#sl-E {{'E' defined here}}
602+
603+
// F inherits D but only an unnamed bitfield
604+
// This should still fail because F ends up with a
605+
// base class with a data member and its own unnamed bitfield
606+
// which is not allowed in standard layout
607+
struct F : D { int : 0; }; // #sl-F
608+
static_assert(__is_standard_layout(F));
609+
// expected-error@-1 {{static assertion failed due to requirement '__is_standard_layout(standard_layout_tests::F)'}} \
610+
// expected-note@-1 {{'F' is not standard-layout}} \
611+
// expected-note@#sl-F {{'F' defined here}}
612+
613+
struct Empty {};
614+
struct G { Empty a, b; }; // #sl-G
615+
static_assert(__is_standard_layout(G)); // no diagnostics
616+
617+
struct H { Empty a; int x; }; // #sl-H
618+
static_assert(__is_standard_layout(H)); // no diagnostics
619+
620+
struct I { Empty a; int : 0; int x; }; // #sl-I
621+
static_assert(__is_standard_layout(I)); // no diagnostics
622+
623+
// [[no_unique_address]] or [[msvc::no_unique_address]] should not affect standard layout
624+
#if __has_cpp_attribute(no_unique_address)
625+
#define NO_UNIQUE_ADDRESS [[no_unique_address]]
626+
#elif __has_cpp_attribute(msvc::no_unique_address)
627+
#define NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
628+
#elif defined(_MSC_VER)
629+
#define NO_UNIQUE_ADDRESS __declspec(no_unique_address)
630+
#else
631+
#define NO_UNIQUE_ADDRESS /* nothing */
632+
#endif
633+
struct J { NO_UNIQUE_ADDRESS Empty a; int x; };
634+
static_assert(__is_standard_layout(J)); // no diagnostics
635+
}

0 commit comments

Comments
 (0)