[clang] [Clang] Add detailed notes explaining why is_aggregate evaluates to false (PR #152488)

Shamshura Egor via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 25 07:23:34 PDT 2025


================
@@ -2639,6 +2642,87 @@ static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
 }
 
+static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc,
+                                       const CXXRecordDecl *D) {
+  for (const CXXConstructorDecl *Ctor : D->ctors()) {
+    if (Ctor->isUserProvided())
+      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+          << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
+    if (Ctor->isInheritingConstructor())
+      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+          << diag::TraitNotSatisfiedReason::InheritedCtr;
+  }
+
+  if (llvm::any_of(D->decls(), [](auto const *Sub) {
+        return isa<ConstructorUsingShadowDecl>(Sub);
+      })) {
+    SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+        << diag::TraitNotSatisfiedReason::InheritedCtr;
+  }
+
+  for (const FieldDecl *Field : D->fields()) {
+    auto AccessSpecifier = Field->getAccess();
+    switch (AccessSpecifier) {
+    case AS_private:
+    case AS_protected:
+      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+          << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
+          << (AccessSpecifier == AS_protected);
+      break;
+    default:
+      break;
+    }
+  }
+
+  for (const CXXBaseSpecifier &B : D->bases()) {
+    if (B.isVirtual()) {
+      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+          << diag::TraitNotSatisfiedReason::VBase << B.getType()
+          << B.getSourceRange();
+      continue;
+    }
+    auto AccessSpecifier = B.getAccessSpecifier();
+    switch (AccessSpecifier) {
+    case AS_private:
+    case AS_protected:
+      SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
+          << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
+          << (AccessSpecifier == AS_protected);
+      break;
+    default:
+      break;
+    }
+  }
+
+  for (const CXXMethodDecl *Method : D->methods()) {
----------------
egorshamshura wrote:

> I suspect a double-note here is even better. First one that says "because it is a polymorphic type", second of: "check out this method here, which is virtual".

Added note about polymorphic type.

https://github.com/llvm/llvm-project/pull/152488


More information about the cfe-commits mailing list