aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:49 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:50:49 +0000
commit2298981669bf3bd63335a4be179bc0f96823a8f4 (patch)
tree1cbe2eb27f030d2d70b80ee5ca3c86bee7326a9f /lib/CodeGen/CGClass.cpp
parent9a83721404652cea39e9f02ae3e3b5c964602a5c (diff)
downloadsrc-2298981669bf3bd63335a4be179bc0f96823a8f4.tar.gz
src-2298981669bf3bd63335a4be179bc0f96823a8f4.zip
Vendor import of stripped clang trunk r366426 (just before thevendor/clang/clang-trunk-r366426
Notes
Notes: svn path=/vendor/clang/dist/; revision=351280 svn path=/vendor/clang/clang-trunk-r366426/; revision=351281; tag=vendor/clang/clang-trunk-r366426
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp127
1 files changed, 75 insertions, 52 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index ee150a792b76..c8bb63c5c4b1 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -1,9 +1,8 @@
//===--- CGClass.cpp - Emit LLVM Code for C++ classes -----------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -303,7 +302,8 @@ Address CodeGenFunction::GetAddressOfBaseClass(
// Get the base pointer type.
llvm::Type *BasePtrTy =
- ConvertType((PathEnd[-1])->getType())->getPointerTo();
+ ConvertType((PathEnd[-1])->getType())
+ ->getPointerTo(Value.getType()->getPointerAddressSpace());
QualType DerivedTy = getContext().getRecordType(Derived);
CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
@@ -491,12 +491,15 @@ namespace {
cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
const CXXDestructorDecl *D = BaseClass->getDestructor();
+ // We are already inside a destructor, so presumably the object being
+ // destroyed should have the expected type.
+ QualType ThisTy = D->getThisObjectType();
Address Addr =
CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(),
DerivedClass, BaseClass,
BaseIsVirtual);
CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual,
- /*Delegating=*/false, Addr);
+ /*Delegating=*/false, Addr, ThisTy);
}
};
@@ -526,8 +529,7 @@ static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) {
static void EmitBaseInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
- CXXCtorInitializer *BaseInit,
- CXXCtorType CtorType) {
+ CXXCtorInitializer *BaseInit) {
assert(BaseInit->isBaseInitializer() &&
"Must have base initializer!");
@@ -539,10 +541,6 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
bool isBaseVirtual = BaseInit->isBaseVirtual();
- // The base constructor doesn't construct virtual bases.
- if (CtorType == Ctor_Base && isBaseVirtual)
- return;
-
// If the initializer for the base (other than the constructor
// itself) accesses 'this' in any way, we need to initialize the
// vtables.
@@ -561,7 +559,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
AggValueSlot::IsDestructed,
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased,
- CGF.overlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual));
+ CGF.getOverlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual));
CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
@@ -650,7 +648,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field);
// Copy the aggregate.
- CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.overlapForFieldInit(Field),
+ CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.getOverlapForFieldInit(Field),
LHS.isVolatileQualified());
// Ensure that we destroy the objects if an exception is thrown later in
// the constructor.
@@ -686,7 +684,7 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
AggValueSlot::IsDestructed,
AggValueSlot::DoesNotNeedGCBarriers,
AggValueSlot::IsNotAliased,
- overlapForFieldInit(Field),
+ getOverlapForFieldInit(Field),
AggValueSlot::IsNotZeroed,
// Checks are made by the code that calls constructor.
AggValueSlot::IsSanitizerChecked);
@@ -793,7 +791,7 @@ void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) {
llvm::Type *Args[2] = {IntPtrTy, IntPtrTy};
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, Args, false);
- llvm::Constant *F = CGM.CreateRuntimeFunction(
+ llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
FTy, Prologue ? "__asan_poison_intra_object_redzone"
: "__asan_unpoison_intra_object_redzone");
@@ -1013,7 +1011,7 @@ namespace {
if (FOffset < FirstFieldOffset) {
FirstField = F;
FirstFieldOffset = FOffset;
- } else if (FOffset > LastFieldOffset) {
+ } else if (FOffset >= LastFieldOffset) {
LastField = F;
LastFieldOffset = FOffset;
}
@@ -1264,24 +1262,37 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
E = CD->init_end();
+ // Virtual base initializers first, if any. They aren't needed if:
+ // - This is a base ctor variant
+ // - There are no vbases
+ // - The class is abstract, so a complete object of it cannot be constructed
+ //
+ // The check for an abstract class is necessary because sema may not have
+ // marked virtual base destructors referenced.
+ bool ConstructVBases = CtorType != Ctor_Base &&
+ ClassDecl->getNumVBases() != 0 &&
+ !ClassDecl->isAbstract();
+
+ // In the Microsoft C++ ABI, there are no constructor variants. Instead, the
+ // constructor of a class with virtual bases takes an additional parameter to
+ // conditionally construct the virtual bases. Emit that check here.
llvm::BasicBlock *BaseCtorContinueBB = nullptr;
- if (ClassDecl->getNumVBases() &&
+ if (ConstructVBases &&
!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
- // The ABIs that don't have constructor variants need to put a branch
- // before the virtual base initialization code.
BaseCtorContinueBB =
- CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
+ CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
assert(BaseCtorContinueBB);
}
llvm::Value *const OldThis = CXXThisValue;
- // Virtual base initializers first.
for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
+ if (!ConstructVBases)
+ continue;
if (CGM.getCodeGenOpts().StrictVTablePointers &&
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
isInitializerOfDynamicClass(*B))
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+ EmitBaseInitializer(*this, ClassDecl, *B);
}
if (BaseCtorContinueBB) {
@@ -1298,7 +1309,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
isInitializerOfDynamicClass(*B))
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B, CtorType);
+ EmitBaseInitializer(*this, ClassDecl, *B);
}
CXXThisValue = OldThis;
@@ -1432,9 +1443,11 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
if (DtorType == Dtor_Deleting) {
RunCleanupsScope DtorEpilogue(*this);
EnterDtorCleanups(Dtor, Dtor_Deleting);
- if (HaveInsertPoint())
+ if (HaveInsertPoint()) {
+ QualType ThisTy = Dtor->getThisObjectType();
EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
- /*Delegating=*/false, LoadCXXThisAddress());
+ /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
+ }
return;
}
@@ -1465,8 +1478,9 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
EnterDtorCleanups(Dtor, Dtor_Complete);
if (!isTryBody) {
+ QualType ThisTy = Dtor->getThisObjectType();
EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
- /*Delegating=*/false, LoadCXXThisAddress());
+ /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
break;
}
@@ -1627,7 +1641,7 @@ namespace {
llvm::FunctionType *FnType =
llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
- llvm::Value *Fn =
+ llvm::FunctionCallee Fn =
CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
CGF.EmitNounwindRuntimeCall(Fn, Args);
}
@@ -1970,10 +1984,14 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
*destroyer);
}
-
+ auto currAVS = AggValueSlot::forAddr(
+ curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
+ AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
+ AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed,
+ NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked
+ : AggValueSlot::IsNotSanitizerChecked);
EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false,
- /*Delegating=*/false, curAddr, E,
- AggValueSlot::DoesNotOverlap, NewPointerIsChecked);
+ /*Delegating=*/false, currAVS, E);
}
// Go to the next element.
@@ -2001,22 +2019,22 @@ void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
const CXXDestructorDecl *dtor = record->getDestructor();
assert(!dtor->isTrivial());
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
- /*Delegating=*/false, addr);
+ /*Delegating=*/false, addr, type);
}
void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
CXXCtorType Type,
bool ForVirtualBase,
- bool Delegating, Address This,
- const CXXConstructExpr *E,
- AggValueSlot::Overlap_t Overlap,
- bool NewPointerIsChecked) {
+ bool Delegating,
+ AggValueSlot ThisAVS,
+ const CXXConstructExpr *E) {
CallArgList Args;
-
- LangAS SlotAS = E->getType().getAddressSpace();
+ Address This = ThisAVS.getAddress();
+ LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace();
QualType ThisType = D->getThisType();
LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace();
llvm::Value *ThisPtr = This.getPointer();
+
if (SlotAS != ThisAS) {
unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS);
llvm::Type *NewType =
@@ -2024,6 +2042,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(),
ThisAS, SlotAS, NewType);
}
+
// Push the this ptr.
Args.add(RValue::get(ThisPtr), D->getThisType());
@@ -2037,7 +2056,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
LValue Src = EmitLValue(Arg);
QualType DestTy = getContext().getTypeDeclType(D->getParent());
LValue Dest = MakeAddrLValue(This, DestTy);
- EmitAggregateCopyCtor(Dest, Src, Overlap);
+ EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap());
return;
}
@@ -2050,7 +2069,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
/*ParamsToSkip*/ 0, Order);
EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
- Overlap, E->getExprLoc(), NewPointerIsChecked);
+ ThisAVS.mayOverlap(), E->getExprLoc(),
+ ThisAVS.isSanitizerChecked());
}
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
@@ -2130,8 +2150,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
Delegating, Args);
// Emit the call.
- llvm::Constant *CalleePtr =
- CGM.getAddrOfCXXStructor(D, getFromCtorType(Type));
+ llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type));
const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
@@ -2350,8 +2369,11 @@ namespace {
: Dtor(D), Addr(Addr), Type(Type) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
+ // We are calling the destructor from within the constructor.
+ // Therefore, "this" should have the expected type.
+ QualType ThisTy = Dtor->getThisObjectType();
CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
- /*Delegating=*/true, Addr);
+ /*Delegating=*/true, Addr, ThisTy);
}
};
} // end anonymous namespace
@@ -2389,31 +2411,32 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor
void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
CXXDtorType Type,
bool ForVirtualBase,
- bool Delegating,
- Address This) {
+ bool Delegating, Address This,
+ QualType ThisTy) {
CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
- Delegating, This);
+ Delegating, This, ThisTy);
}
namespace {
struct CallLocalDtor final : EHScopeStack::Cleanup {
const CXXDestructorDecl *Dtor;
Address Addr;
+ QualType Ty;
- CallLocalDtor(const CXXDestructorDecl *D, Address Addr)
- : Dtor(D), Addr(Addr) {}
+ CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty)
+ : Dtor(D), Addr(Addr), Ty(Ty) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false,
- /*Delegating=*/false, Addr);
+ /*Delegating=*/false, Addr, Ty);
}
};
} // end anonymous namespace
void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
- Address Addr) {
- EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr);
+ QualType T, Address Addr) {
+ EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T);
}
void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
@@ -2423,7 +2446,7 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
const CXXDestructorDecl *D = ClassDecl->getDestructor();
assert(D && D->isUsed() && "destructor not marked as used!");
- PushDestructorCleanup(D, Addr);
+ PushDestructorCleanup(D, T, Addr);
}
void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {