summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorPiotr Padlewski <prazek@google.com>2015-10-02 22:12:40 +0000
committerPiotr Padlewski <prazek@google.com>2015-10-02 22:12:40 +0000
commit276a78d860cbe376202d3251a1f490b0da7f2f7e (patch)
treeef6ac2f6a4e0b0b69d1d75731586decdb58f5fc4 /clang/lib
parentdc9b2cfc5013684456ec7d632eaa2edf7c030f2b (diff)
downloadbcm5719-llvm-276a78d860cbe376202d3251a1f490b0da7f2f7e.tar.gz
bcm5719-llvm-276a78d860cbe376202d3251a1f490b0da7f2f7e.zip
Emiting invariant.group.barrier for ctors bugfix
Ensure that the vptr store in the most-derived constructor is not behind an invariant group barrier. Previously, the base-most vptr store would be the one behind no barrier, and that could result in the creator of the object thinking it had the base-most vtable. This bug caused clang call pure virtual functions when called from constructor body. http://reviews.llvm.org/D13373 llvm-svn: 249197
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 6394d1ff17d..5c08f67d402 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1375,13 +1375,14 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
assert(BaseCtorContinueBB);
}
- bool BaseVPtrsInitialized = false;
+ llvm::Value *const OldThis = CXXThisValue;
// Virtual base initializers first.
for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
- CXXCtorInitializer *BaseInit = *B;
+ if (CGM.getCodeGenOpts().StrictVTablePointers &&
+ CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ isInitializerOfDynamicClass(*B))
+ CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
- BaseVPtrsInitialized |= BaseInitializerUsesThis(getContext(),
- BaseInit->getInit());
}
if (BaseCtorContinueBB) {
@@ -1393,15 +1394,15 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
// Then, non-virtual base initializers.
for (; B != E && (*B)->isBaseInitializer(); B++) {
assert(!(*B)->isBaseVirtual());
+
+ if (CGM.getCodeGenOpts().StrictVTablePointers &&
+ CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ isInitializerOfDynamicClass(*B))
+ CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
- BaseVPtrsInitialized |= isInitializerOfDynamicClass(*B);
}
- // Pointer to this requires to be passed through invariant.group.barrier
- // only if we've initialized any base vptrs.
- if (CGM.getCodeGenOpts().StrictVTablePointers &&
- CGM.getCodeGenOpts().OptimizationLevel > 0 && BaseVPtrsInitialized)
- CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
+ CXXThisValue = OldThis;
InitializeVTablePointers(ClassDecl);
OpenPOWER on IntegriCloud