aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-07-07 06:59:51 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-07-07 06:59:51 +0000
commitff817f7070c0308e9d4486432b774005d4f8e420 (patch)
treee6285ec9559b2ec29884d288587eebeab57d5f4a /lib/Sema/SemaDeclCXX.cpp
parent0f3d0970dcdf6cf17550b86838dff12813968dbc (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.cpp25
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.