MS ABI: Don't be so hasty to judge an inheritance model
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 7 Feb 2014 00:43:07 +0000 (00:43 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 7 Feb 2014 00:43:07 +0000 (00:43 +0000)
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

clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/SemaCXX/member-pointer-ms.cpp

index 8b75081..dd059bb 100644 (file)
@@ -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());
index 50ec236..66591e4 100644 (file)
@@ -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
index aa3caa7..8e80940 100644 (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}}
  // expected-note@-1 {{C defined here}}
+
+struct __virtual_inheritance D;
+struct D : virtual B {};
 }