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.

llvm-svn: 200959
This commit is contained in:
David Majnemer 2014-02-07 00:43:07 +00:00
parent 37c9267107
commit 98c9ee2068
3 changed files with 20 additions and 10 deletions

View File

@ -12150,7 +12150,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (Record->hasAttrs()) { if (Record->hasAttrs()) {
CheckAlignasUnderalignment(Record); CheckAlignasUnderalignment(Record);
if (MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>()) if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record), checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
IA->getRange(), IA->getRange(),
IA->getSemanticSpelling()); IA->getSemanticSpelling());

View File

@ -2877,16 +2877,23 @@ bool Sema::checkMSInheritanceAttrOnDefinition(
MSInheritanceAttr::Spelling SemanticSpelling) { MSInheritanceAttr::Spelling SemanticSpelling) {
assert(RD->hasDefinition() && "RD has no definition!"); assert(RD->hasDefinition() && "RD has no definition!");
if (SemanticSpelling != MSInheritanceAttr::Keyword_unspecified_inheritance && // We may not have seen base specifiers or any virtual methods yet. We will
RD->calculateInheritanceModel() != SemanticSpelling) { // have to wait until the record is defined to catch any mismatches.
Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance) if (!RD->getDefinition()->isCompleteDefinition())
<< 0 /*definition*/; return false;
Diag(RD->getDefinition()->getLocation(), diag::note_defined_here)
<< RD->getNameAsString();
return true;
}
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 /// handleModeAttr - This attribute modifies the width of a decl with primitive

View File

@ -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}} struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}}
// expected-note@-1 {{C defined here}} // expected-note@-1 {{C defined here}}
struct __virtual_inheritance D;
struct D : virtual B {};
} }