From e1b1adc8bd32db2fc0c9f4b24bd57ffe5dcc2d04 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 26 Aug 2014 23:29:11 +0000 Subject: [PATCH] [modules] Don't assert when merging virtual functions that override other 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 | 17 ++++++++++++----- test/Modules/Inputs/cxx-decls-imported.h | 7 +++++++ test/Modules/Inputs/cxx-decls-merged.h | 8 ++++++++ test/Modules/cxx-decls.cpp | 3 +++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 5f7a93f132..0aa2923991 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -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(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(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; } } diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h index a30db940a1..ccf1cb2b35 100644 --- a/test/Modules/Inputs/cxx-decls-imported.h +++ b/test/Modules/Inputs/cxx-decls-imported.h @@ -28,3 +28,10 @@ typedef struct { int n; int m; } NameForLinkage; + +struct HasVirtualFunctions { + virtual void f(); +}; +struct OverridesVirtualFunctions : HasVirtualFunctions { + void f(); +}; diff --git a/test/Modules/Inputs/cxx-decls-merged.h b/test/Modules/Inputs/cxx-decls-merged.h index b1ed2a0d93..3f9da1a55e 100644 --- a/test/Modules/Inputs/cxx-decls-merged.h +++ b/test/Modules/Inputs/cxx-decls-merged.h @@ -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; diff --git a/test/Modules/cxx-decls.cpp b/test/Modules/cxx-decls.cpp index 678f245ed1..ee196cfc33 100644 --- a/test/Modules/cxx-decls.cpp +++ b/test/Modules/cxx-decls.cpp @@ -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 -- 2.40.0