]> granicus.if.org Git - clang/commitdiff
[modules] Don't assert when merging virtual functions that override other
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 26 Aug 2014 23:29:11 +0000 (23:29 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 26 Aug 2014 23:29:11 +0000 (23:29 +0000)
functions. Also don't needlessly pull in non-canonical declarations of the
overridden virtual functions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216503 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/cxx-decls-imported.h
test/Modules/Inputs/cxx-decls-merged.h
test/Modules/cxx-decls.cpp

index 5f7a93f13202692c9f1b582a3c5530a867a2342a..0aa2923991552ae96ecb33a107239a387a7a22d5 100644 (file)
@@ -1504,12 +1504,19 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
 
 void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
   VisitFunctionDecl(D);
+
   unsigned NumOverridenMethods = Record[Idx++];
-  while (NumOverridenMethods--) {
-    // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
-    // MD may be initializing.
-    if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
-      Reader.getContext().addOverriddenMethod(D, MD);
+  if (D->isCanonicalDecl()) {
+    while (NumOverridenMethods--) {
+      // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod,
+      // MD may be initializing.
+      if (CXXMethodDecl *MD = ReadDeclAs<CXXMethodDecl>(Record, Idx))
+        Reader.getContext().addOverriddenMethod(D, MD->getCanonicalDecl());
+    }
+  } else {
+    // We don't care about which declarations this used to override; we get
+    // the relevant information from the canonical declaration.
+    Idx += NumOverridenMethods;
   }
 }
 
index a30db940a19303c623f3b3a853d99638ca37c9f1..ccf1cb2b359623996f9797181221fcf721b28be8 100644 (file)
@@ -28,3 +28,10 @@ typedef struct {
   int n;
   int m;
 } NameForLinkage;
+
+struct HasVirtualFunctions {
+  virtual void f();
+};
+struct OverridesVirtualFunctions : HasVirtualFunctions {
+  void f();
+};
index b1ed2a0d932674fbaec9ab7eae64e525a5bd4320..3f9da1a55ee3d303038048ee794f5c5a98229bc4 100644 (file)
@@ -5,3 +5,11 @@ typedef struct {
   int m;
 } NameForLinkage;
 extern NameForLinkage name_for_linkage;
+
+struct HasVirtualFunctions {
+  virtual void f();
+};
+struct OverridesVirtualFunctions : HasVirtualFunctions {
+  void f();
+};
+extern OverridesVirtualFunctions overrides_virtual_functions;
index 678f245ed104c6e31c07a89caaf1269e16ecff70..ee196cfc33b8854352a3bd9984568d14ae0757b5 100644 (file)
@@ -33,10 +33,13 @@ int importMergeUsedFlag = getMergeUsedFlag();
 int use_name_for_linkage(NameForLinkage &nfl) {
   return nfl.n + nfl.m;
 }
+int use_overrides_virtual_functions(OverridesVirtualFunctions ovf) { return 0; }
 
 @import cxx_decls_merged;
 
 int name_for_linkage_test = use_name_for_linkage(name_for_linkage);
+int overrides_virtual_functions_test =
+    use_overrides_virtual_functions(overrides_virtual_functions);
 
 // CHECK: VarDecl [[mergeUsedFlag:0x[0-9a-f]*]] {{.*}} in cxx_decls.imported used mergeUsedFlag
 // CHECK: VarDecl {{0x[0-9a-f]*}} prev [[mergeUsedFlag]] {{.*}} in cxx_decls_merged used mergeUsedFlag