[clang] [Clang] Implement diagnostics for why `std::is_standard_layout` is false (PR #144161)
Samarth Narang via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 25 06:20:38 PDT 2025
================
@@ -2285,6 +2286,139 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
}
+static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D) {
+ int NumBasesWithFields = 0;
+ for (const CXXBaseSpecifier &Base : D->bases()) {
+ const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
+ if (!BaseRD || BaseRD->isInvalidDecl())
+ continue;
+
+ for (const FieldDecl *Field : BaseRD->fields()) {
+ if (!Field->isUnnamedBitField()) {
+ if (++NumBasesWithFields > 1)
+ return true; // found more than one base class with fields
+ break; // no need to check further fields in this base class
+ }
+ }
+ }
+ return false;
+}
+
+static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
+ const CXXRecordDecl *D) {
+ for (const CXXBaseSpecifier &B : D->bases()) {
+ assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
+ if (B.isVirtual()) {
+ SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+ << diag::TraitNotSatisfiedReason::VBase << B.getType()
+ << B.getSourceRange();
+ }
+ if (!B.getType()->isStandardLayoutType()) {
+ SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+ << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
+ << B.getSourceRange();
+ }
+ }
+ // Check for mixed access specifiers in fields.
+ const FieldDecl *FirstField = nullptr;
+ AccessSpecifier FirstAccess = AS_none;
+
+ for (const FieldDecl *Field : D->fields()) {
+ if (Field->isUnnamedBitField())
+ continue;
+
+ // Record the first field we see
+ if (!FirstField) {
+ FirstField = Field;
+ FirstAccess = Field->getAccess();
+ continue;
+ }
+
+ // Check if the field has a different access specifier than the first one.
+ if (Field->getAccess() != FirstAccess) {
+ // Emit a diagnostic about mixed access specifiers.
+ SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+ << diag::TraitNotSatisfiedReason::MixedAccess;
+
+ SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
+ << FirstField;
+
+ SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
+ << diag::TraitNotSatisfiedReason::MixedAccessField << Field
+ << FirstField;
+
+ // No need to check further fields, as we already found mixed access.
+ return;
----------------
snarang181 wrote:
You are correct, this should be a `break`.
https://github.com/llvm/llvm-project/pull/144161
More information about the cfe-commits
mailing list