Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2564,7 +2564,7 @@ def note_previous_attribute : Note<"previous attribute is here">; def note_attribute : Note<"attribute is here">; def err_mismatched_ms_inheritance : Error< - "inheritance model does not match %select{definition|previous declaration}0">; + "inheritance model does not match %select{definition|previous declaration}0 (%select{single|multiple|virtual|most general}1 vs %select{single|multiple|virtual|most general}2)">; def warn_ignored_ms_inheritance : Warning< "inheritance model ignored on %select{primary template|partial specialization}0">, InGroup; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -2863,16 +2863,19 @@ if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) return false; + MSInheritanceAttr::Spelling CalculatedInheritanceModel = + RD->calculateInheritanceModel(); if (BestCase) { - if (RD->calculateInheritanceModel() == SemanticSpelling) + if (CalculatedInheritanceModel == SemanticSpelling) return false; } else { - if (RD->calculateInheritanceModel() <= SemanticSpelling) + if (CalculatedInheritanceModel <= SemanticSpelling) return false; } Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) - << 0 /*definition*/; + << 0 /*definition*/ << SemanticSpelling << CalculatedInheritanceModel; + Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD->getNameAsString(); return true; @@ -3892,7 +3895,8 @@ if (IA->getSemanticSpelling() == SemanticSpelling) return nullptr; Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance) - << 1 /*previous declaration*/; + << 1 /*previous declaration*/ << SemanticSpelling + << IA->getSemanticSpelling(); Diag(Range.getBegin(), diag::note_previous_ms_inheritance); D->dropAttr(); } Index: test/SemaCXX/member-pointer-ms.cpp =================================================================== --- test/SemaCXX/member-pointer-ms.cpp +++ test/SemaCXX/member-pointer-ms.cpp @@ -248,6 +248,18 @@ struct __virtual_inheritance D; struct D : virtual B {}; } + +#ifdef VMB +namespace WarnTest { +struct A {}; +struct B : A { // expected-error {{inheritance model does not match definition (single vs multiple)}} + // expected-note@-1 {{B defined here}} + int B::*x; + virtual void f(); +}; +} +#endif + #ifdef VMB namespace PR20017 {