diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-07 06:59:51 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-07 06:59:51 +0000 |
commit | ff817f7070c0308e9d4486432b774005d4f8e420 (patch) | |
tree | e6285ec9559b2ec29884d288587eebeab57d5f4a /lib/Sema/SemaDeclCXX.cpp | |
parent | 0f3d0970dcdf6cf17550b86838dff12813968dbc (diff) |
When marking virtual functions as used for a class' vtable, mark all functions
which will appear in the vtable as used, not just those ones which were
declared within the class itself. Fixes an issue reported as comment#3 in
PR12763 -- we sometimes assert in codegen if we try to emit a reference to a
function declaration which we've not marked as referenced. This also matches
gcc's observed behavior.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159895 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index fc631d0d87..32708090c9 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -10795,14 +10795,23 @@ bool Sema::DefineUsedVTables() { void Sema::MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD) { - for (CXXRecordDecl::method_iterator i = RD->method_begin(), - e = RD->method_end(); i != e; ++i) { - CXXMethodDecl *MD = *i; - - // C++ [basic.def.odr]p2: - // [...] A virtual member function is used if it is not pure. [...] - if (MD->isVirtual() && !MD->isPure()) - MarkFunctionReferenced(Loc, MD); + // Mark all functions which will appear in RD's vtable as used. + CXXFinalOverriderMap FinalOverriders; + RD->getFinalOverriders(FinalOverriders); + for (CXXFinalOverriderMap::const_iterator I = FinalOverriders.begin(), + E = FinalOverriders.end(); + I != E; ++I) { + for (OverridingMethods::const_iterator OI = I->second.begin(), + OE = I->second.end(); + OI != OE; ++OI) { + assert(OI->second.size() > 0 && "no final overrider"); + CXXMethodDecl *Overrider = OI->second.front().Method; + + // C++ [basic.def.odr]p2: + // [...] A virtual member function is used if it is not pure. [...] + if (!Overrider->isPure()) + MarkFunctionReferenced(Loc, Overrider); + } } // Only classes that have virtual bases need a VTT. |