================ @@ -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; ---------------- AaronBallman wrote:
Shouldn't this be a `break`? Otherwise we'll emit the note for access specifiers and miss additional notes about polymorphism, etc. (Are we missing test coverage for that case?) https://github.com/llvm/llvm-project/pull/144161 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits