@@ -2353,32 +2353,17 @@ static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
23532353 << Field->getType () << Field->getSourceRange ();
23542354 }
23552355 }
2356-
2357- // if this class and an indirect base
2358- // both have non-static data members, grab the first such base.
2356+ // find any indirect base classes that have fields
23592357 if (D->hasDirectFields ()) {
2360- SmallVector<const CXXRecordDecl *, 4 > Records;
2361-
2362- // Recursive lambda to collect all bases that declare fields
2363- std::function<void (const CXXRecordDecl *)> collect =
2364- [&](const CXXRecordDecl *R) {
2365- for (const CXXBaseSpecifier &B : R->bases ()) {
2366- const auto *BR = B.getType ()->getAsCXXRecordDecl ();
2367- if (!BR || !BR->hasDefinition ())
2368- continue ;
2369- if (BR->hasDirectFields ())
2370- Records.push_back (BR);
2371- // Recurse into the base class.
2372- collect (BR);
2373- }
2374- };
2375-
2376- // Collect all bases that declare fields.
2377- collect (D);
2378-
2379- // If more than one record has fields, then the layout is non-standard.
2380- if (!Records.empty ()) {
2381- const CXXRecordDecl *Indirect = Records.front ();
2358+ const CXXRecordDecl *Indirect = nullptr ;
2359+ D->forallBases ([&](const CXXRecordDecl *BaseDef) {
2360+ if (BaseDef->hasDirectFields ()) {
2361+ Indirect = BaseDef;
2362+ return false ; // stop traversal
2363+ }
2364+ return true ; // continue to the next base
2365+ });
2366+ if (Indirect) {
23822367 SemaRef.Diag (Loc, diag::note_unsatisfied_trait_reason)
23832368 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
23842369 << Indirect->getSourceRange ();
0 commit comments