From 61a09b7d35b270bd78c7869fa524f5071fffdd1c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Fri, 7 Feb 2014 00:43:07 +0000 Subject: [PATCH] MS ABI: Don't be so hasty to judge an inheritance model If we are in the middle of defining the class, don't attempt to validate previously annotated declarations. We may not have seen base specifiers or virtual method declarations yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200959 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 2 +- lib/Sema/SemaDeclAttr.cpp | 25 ++++++++++++++++--------- test/SemaCXX/member-pointer-ms.cpp | 3 +++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8b750812d9..dd059bbb09 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12150,7 +12150,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (Record->hasAttrs()) { CheckAlignasUnderalignment(Record); - if (MSInheritanceAttr *IA = Record->getAttr()) + if (const MSInheritanceAttr *IA = Record->getAttr()) checkMSInheritanceAttrOnDefinition(cast(Record), IA->getRange(), IA->getSemanticSpelling()); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 50ec236fb7..66591e4bf3 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -2877,16 +2877,23 @@ bool Sema::checkMSInheritanceAttrOnDefinition( MSInheritanceAttr::Spelling SemanticSpelling) { assert(RD->hasDefinition() && "RD has no definition!"); - if (SemanticSpelling != MSInheritanceAttr::Keyword_unspecified_inheritance && - RD->calculateInheritanceModel() != SemanticSpelling) { - Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) - << 0 /*definition*/; - Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) - << RD->getNameAsString(); - return true; - } + // We may not have seen base specifiers or any virtual methods yet. We will + // have to wait until the record is defined to catch any mismatches. + if (!RD->getDefinition()->isCompleteDefinition()) + return false; - return false; + // The unspecified model never matches what a definition could need. + if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) + return false; + + if (RD->calculateInheritanceModel() == SemanticSpelling) + return false; + + Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) + << 0 /*definition*/; + Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) + << RD->getNameAsString(); + return true; } /// handleModeAttr - This attribute modifies the width of a decl with primitive diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp index aa3caa7428..8e8094004f 100644 --- a/test/SemaCXX/member-pointer-ms.cpp +++ b/test/SemaCXX/member-pointer-ms.cpp @@ -198,4 +198,7 @@ struct __multiple_inheritance B; // expected-error{{inheritance model does not m struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}} // expected-note@-1 {{C defined here}} + +struct __virtual_inheritance D; +struct D : virtual B {}; } -- 2.40.0