Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9395,6 +9395,8 @@ def err_incorrect_defaulted_constexpr : Error< "defaulted definition of %sub{select_special_member_kind}0 " "is not constexpr">; +def err_incorrect_defaulted_constexpr_with_vb: Error< + "%sub{select_special_member_kind}0 cannot be 'constexpr' in a class with virtual base class">; def err_incorrect_defaulted_consteval : Error< "defaulted declaration of %sub{select_special_member_kind}0 " "cannot be consteval because implicit definition is not constexpr">; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -7800,10 +7800,17 @@ : isa(MD))) && MD->isConstexpr() && !Constexpr && MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) { - Diag(MD->getBeginLoc(), MD->isConsteval() - ? diag::err_incorrect_defaulted_consteval - : diag::err_incorrect_defaulted_constexpr) - << CSM; + if (!MD->isConsteval() && RD->getNumVBases()) { + Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr_with_vb) + << CSM; + for (const auto &I : RD->vbases()) + Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here); + } else { + Diag(MD->getBeginLoc(), MD->isConsteval() + ? diag::err_incorrect_defaulted_consteval + : diag::err_incorrect_defaulted_constexpr) + << CSM; + } // FIXME: Explain why the special member can't be constexpr. HadError = true; }