diff options
| author | Piotr Padlewski <prazek@google.com> | 2015-10-02 22:12:40 +0000 |
|---|---|---|
| committer | Piotr Padlewski <prazek@google.com> | 2015-10-02 22:12:40 +0000 |
| commit | 276a78d860cbe376202d3251a1f490b0da7f2f7e (patch) | |
| tree | ef6ac2f6a4e0b0b69d1d75731586decdb58f5fc4 /clang/lib | |
| parent | dc9b2cfc5013684456ec7d632eaa2edf7c030f2b (diff) | |
| download | bcm5719-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.cpp | 21 |
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); |

