summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-02-07 00:43:07 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-02-07 00:43:07 +0000
commit98c9ee2068dc94d2b3f595545b10ef57503acd4b (patch)
tree1b656eb06e43f9b7e4cc140a259cda6a08cb2922
parent37c9267107ba4e800e5ab9400e681cca2cb31e73 (diff)
downloadbcm5719-llvm-98c9ee2068dc94d2b3f595545b10ef57503acd4b.tar.gz
bcm5719-llvm-98c9ee2068dc94d2b3f595545b10ef57503acd4b.zip
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
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp25
-rw-r--r--clang/test/SemaCXX/member-pointer-ms.cpp3
3 files changed, 20 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 8b750812d9c..dd059bbb098 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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<MSInheritanceAttr>())
+ if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
IA->getRange(),
IA->getSemanticSpelling());
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 50ec236fb79..66591e4bf36 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/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/clang/test/SemaCXX/member-pointer-ms.cpp b/clang/test/SemaCXX/member-pointer-ms.cpp
index aa3caa74285..8e8094004f6 100644
--- a/clang/test/SemaCXX/member-pointer-ms.cpp
+++ b/clang/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 {};
}
OpenPOWER on IntegriCloud