diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp | 158 |
1 files changed, 94 insertions, 64 deletions
diff --git a/gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp b/gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp index c32f1e5415d..f29ef754c03 100644 --- a/gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp +++ b/gnu/llvm/tools/clang/lib/CodeGen/CGExprCXX.cpp @@ -242,16 +242,20 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( } } - Address This = Address::invalid(); - if (IsArrow) - This = EmitPointerWithAlignment(Base); - else - This = EmitLValue(Base).getAddress(); + LValue This; + if (IsArrow) { + LValueBaseInfo BaseInfo; + TBAAAccessInfo TBAAInfo; + Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo); + This = MakeAddrLValue(ThisValue, Base->getType(), BaseInfo, TBAAInfo); + } else { + This = EmitLValue(Base); + } if (MD->isTrivial() || (MD->isDefaulted() && MD->getParent()->isUnion())) { if (isa<CXXDestructorDecl>(MD)) return RValue::get(nullptr); - if (isa<CXXConstructorDecl>(MD) && + if (isa<CXXConstructorDecl>(MD) && cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) return RValue::get(nullptr); @@ -261,10 +265,10 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( // when it isn't necessary; just produce the proper effect here. LValue RHS = isa<CXXOperatorCallExpr>(CE) ? MakeNaturalAlignAddrLValue( - (*RtlArgs)[0].RV.getScalarVal(), + (*RtlArgs)[0].getRValue(*this).getScalarVal(), (*(CE->arg_begin() + 1))->getType()) : EmitLValue(*CE->arg_begin()); - EmitAggregateAssign(This, RHS.getAddress(), CE->getType()); + EmitAggregateAssign(This, RHS, CE->getType()); return RValue::get(This.getPointer()); } @@ -272,8 +276,13 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) { // Trivial move and copy ctor are the same. assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); - Address RHS = EmitLValue(*CE->arg_begin()).getAddress(); - EmitAggregateCopy(This, RHS, (*CE->arg_begin())->getType()); + const Expr *Arg = *CE->arg_begin(); + LValue RHS = EmitLValue(Arg); + LValue Dest = MakeAddrLValue(This.getAddress(), Arg->getType()); + // This is the MSVC p->Ctor::Ctor(...) extension. We assume that's + // constructing a new complete object of type Ctor. + EmitAggregateCopy(Dest, RHS, Arg->getType(), + AggValueSlot::DoesNotOverlap); return RValue::get(This.getPointer()); } llvm_unreachable("unknown trivial member function"); @@ -328,14 +337,15 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( // We also don't emit a virtual call if the base expression has a record type // because then we know what the type is. bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod; - + if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) { assert(CE->arg_begin() == CE->arg_end() && "Destructor shouldn't have explicit parameters"); assert(ReturnValue.isNull() && "Destructor shouldn't have return value"); if (UseVirtualCall) { CGM.getCXXABI().EmitVirtualDestructorCall( - *this, Dtor, Dtor_Complete, This, cast<CXXMemberCallExpr>(CE)); + *this, Dtor, Dtor_Complete, This.getAddress(), + cast<CXXMemberCallExpr>(CE)); } else { CGCallee Callee; if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier) @@ -357,22 +367,22 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( } return RValue::get(nullptr); } - + CGCallee Callee; if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) { Callee = CGCallee::forDirect( CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty), Ctor); } else if (UseVirtualCall) { - Callee = CGM.getCXXABI().getVirtualFunctionPointer(*this, MD, This, Ty, - CE->getLocStart()); + Callee = CGCallee::forVirtual(CE, MD, This.getAddress(), Ty); } else { if (SanOpts.has(SanitizerKind::CFINVCall) && MD->getParent()->isDynamicClass()) { llvm::Value *VTable; const CXXRecordDecl *RD; std::tie(VTable, RD) = - CGM.getCXXABI().LoadVTablePtr(*this, This, MD->getParent()); + CGM.getCXXABI().LoadVTablePtr(*this, This.getAddress(), + MD->getParent()); EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->getLocStart()); } @@ -388,8 +398,10 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( } if (MD->isVirtual()) { - This = CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall( - *this, CalleeDecl, This, UseVirtualCall); + Address NewThisAddr = + CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall( + *this, CalleeDecl, This.getAddress(), UseVirtualCall); + This.setAddress(NewThisAddr); } return EmitCXXMemberOrOperatorCall( @@ -404,20 +416,20 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, cast<BinaryOperator>(E->getCallee()->IgnoreParens()); const Expr *BaseExpr = BO->getLHS(); const Expr *MemFnExpr = BO->getRHS(); - - const MemberPointerType *MPT = + + const MemberPointerType *MPT = MemFnExpr->getType()->castAs<MemberPointerType>(); - const FunctionProtoType *FPT = + const FunctionProtoType *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>(); - const CXXRecordDecl *RD = + const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); // Emit the 'this' pointer. Address This = Address::invalid(); if (BO->getOpcode() == BO_PtrMemI) This = EmitPointerWithAlignment(BaseExpr); - else + else This = EmitLValue(BaseExpr).getAddress(); EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(), @@ -431,10 +443,10 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, CGCallee Callee = CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This, ThisPtrForCall, MemFnPtr, MPT); - + CallArgList Args; - QualType ThisType = + QualType ThisType = getContext().getPointerType(getContext().getTagDeclType(RD)); // Push the this ptr. @@ -558,7 +570,7 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest) { assert(!Dest.isIgnored() && "Must have a destination!"); const CXXConstructorDecl *CD = E->getConstructor(); - + // If we require zero initialization before (or instead of) calling the // constructor, as can be the case with a non-user-provided default // constructor, emit the zero initialization now, unless destination is @@ -576,11 +588,11 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, break; } } - + // If this is a call to a trivial default constructor, do nothing. if (CD->isTrivial() && CD->isDefaultConstructor()) return; - + // Elide the constructor if we're constructing from a temporary. // The temporary check is required because Sema sets this on NRVO // returns. @@ -592,15 +604,16 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, return; } } - + if (const ArrayType *arrayType = getContext().getAsArrayType(E->getType())) { - EmitCXXAggrConstructorCall(CD, arrayType, Dest.getAddress(), E); + EmitCXXAggrConstructorCall(CD, arrayType, Dest.getAddress(), E, + Dest.isSanitizerChecked()); } else { CXXCtorType Type = Ctor_Complete; bool ForVirtualBase = false; bool Delegating = false; - + switch (E->getConstructionKind()) { case CXXConstructExpr::CK_Delegating: // We should be emitting a constructor; GlobalDecl will assert this @@ -619,10 +632,11 @@ CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E, case CXXConstructExpr::CK_NonVirtualBase: Type = Ctor_Base; } - + // Call the constructor. EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, - Dest.getAddress(), E); + Dest.getAddress(), E, Dest.mayOverlap(), + Dest.isSanitizerChecked()); } } @@ -630,19 +644,19 @@ void CodeGenFunction::EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp) { if (const ExprWithCleanups *E = dyn_cast<ExprWithCleanups>(Exp)) Exp = E->getSubExpr(); - assert(isa<CXXConstructExpr>(Exp) && + assert(isa<CXXConstructExpr>(Exp) && "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr"); const CXXConstructExpr* E = cast<CXXConstructExpr>(Exp); const CXXConstructorDecl *CD = E->getConstructor(); RunCleanupsScope Scope(*this); - + // If we require zero initialization before (or instead of) calling the // constructor, as can be the case with a non-user-provided default // constructor, emit the zero initialization now. // FIXME. Do I still need this for a copy ctor synthesis? if (E->requiresZeroInitialization()) EmitNullInitialization(Dest, E->getType()); - + assert(!getContext().getAsConstantArrayType(E->getType()) && "EmitSynthesizedCXXCopyCtor - Copied-in Array"); EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E); @@ -697,7 +711,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, // size_t. That's just a gloss, though, and it's wrong in one // important way: if the count is negative, it's an error even if // the cookie size would bring the total size >= 0. - bool isSigned + bool isSigned = e->getArraySize()->getType()->isSignedIntegerOrEnumerationType(); llvm::IntegerType *numElementsType = cast<llvm::IntegerType>(numElements->getType()); @@ -717,7 +731,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, // This will be a size_t. llvm::Value *size; - + // If someone is doing 'new int[42]' there is no need to do a dynamic check. // Don't bloat the -O0 code. if (llvm::ConstantInt *numElementsC = @@ -808,7 +822,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, } else if (isSigned) { if (numElementsWidth < sizeWidth) numElements = CGF.Builder.CreateSExt(numElements, CGF.SizeTy); - + // If there's a non-1 type size multiplier, then we can do the // signedness check at the same time as we do the multiply // because a negative number times anything will cause an @@ -885,7 +899,7 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, // numElements doesn't need to be scaled. assert(arraySizeMultiplier == 1); } - + // Add in the cookie size if necessary. if (cookieSize != 0) { sizeWithoutCookie = size; @@ -924,7 +938,8 @@ static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, } static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, - QualType AllocType, Address NewPtr) { + QualType AllocType, Address NewPtr, + AggValueSlot::Overlap_t MayOverlap) { // FIXME: Refactor with EmitExprAsInit. switch (CGF.getEvaluationKind(AllocType)) { case TEK_Scalar: @@ -940,7 +955,9 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, = AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased); + AggValueSlot::IsNotAliased, + MayOverlap, AggValueSlot::IsNotZeroed, + AggValueSlot::IsSanitizerChecked); CGF.EmitAggExpr(Init, Slot); return; } @@ -1009,7 +1026,10 @@ void CodeGenFunction::EmitNewArrayInitializer( AggValueSlot::forAddr(CurPtr, ElementType.getQualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased); + AggValueSlot::IsNotAliased, + AggValueSlot::DoesNotOverlap, + AggValueSlot::IsNotZeroed, + AggValueSlot::IsSanitizerChecked); EmitAggExpr(ILE->getInit(0), Slot); // Move past these elements. @@ -1074,7 +1094,8 @@ void CodeGenFunction::EmitNewArrayInitializer( // an array, and we have an array filler, we can fold together the two // initialization loops. StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), - ILE->getInit(i)->getType(), CurPtr); + ILE->getInit(i)->getType(), CurPtr, + AggValueSlot::DoesNotOverlap); CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(), Builder.getSize(1), "array.exp.next"), @@ -1138,6 +1159,7 @@ void CodeGenFunction::EmitNewArrayInitializer( NumElements, llvm::ConstantInt::get(NumElements->getType(), InitListElements)); EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE, + /*NewPointerIsChecked*/true, CCE->requiresZeroInitialization()); return; } @@ -1214,7 +1236,7 @@ void CodeGenFunction::EmitNewArrayInitializer( CurPtr = Address(CurPtrPhi, ElementAlign); // Store the new Cleanup position for irregular Cleanups. - if (EndOfInit.isValid()) + if (EndOfInit.isValid()) Builder.CreateStore(CurPtr.getPointer(), EndOfInit); // Enter a partial-destruction Cleanup if necessary. @@ -1227,7 +1249,8 @@ void CodeGenFunction::EmitNewArrayInitializer( } // Emit the initializer into this element. - StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr); + StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr, + AggValueSlot::DoesNotOverlap); // Leave the Cleanup if we entered one. if (CleanupDominator) { @@ -1258,7 +1281,8 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, CGF.EmitNewArrayInitializer(E, ElementType, ElementTy, NewPtr, NumElements, AllocSizeWithoutCookie); else if (const Expr *Init = E->getInitializer()) - StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr); + StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr, + AggValueSlot::DoesNotOverlap); } /// Emit a call to an operator new or operator delete function, as implicitly @@ -1298,19 +1322,19 @@ static RValue EmitNewDeleteCall(CodeGenFunction &CGF, } RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, - const Expr *Arg, + const CallExpr *TheCall, bool IsDelete) { CallArgList Args; - const Stmt *ArgS = Arg; - EmitCallArgs(Args, *Type->param_type_begin(), llvm::makeArrayRef(ArgS)); + EmitCallArgs(Args, Type->getParamTypes(), TheCall->arguments()); // Find the allocation or deallocation function that we're calling. ASTContext &Ctx = getContext(); DeclarationName Name = Ctx.DeclarationNames .getCXXOperatorName(IsDelete ? OO_Delete : OO_New); + for (auto *Decl : Ctx.getTranslationUnitDecl()->lookup(Name)) if (auto *FD = dyn_cast<FunctionDecl>(Decl)) if (Ctx.hasSameType(FD->getType(), QualType(Type, 0))) - return EmitNewDeleteCall(*this, cast<FunctionDecl>(Decl), Type, Args); + return EmitNewDeleteCall(*this, FD, Type, Args); llvm_unreachable("predeclared global operator new/delete is missing"); } @@ -1481,7 +1505,7 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, AllocAlign); for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { auto &Arg = NewArgs[I + NumNonPlacementArgs]; - Cleanup->setPlacementArg(I, Arg.RV, Arg.Ty); + Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty); } return; @@ -1512,8 +1536,8 @@ static void EnterNewDeleteCleanup(CodeGenFunction &CGF, AllocAlign); for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) { auto &Arg = NewArgs[I + NumNonPlacementArgs]; - Cleanup->setPlacementArg(I, DominatingValue<RValue>::save(CGF, Arg.RV), - Arg.Ty); + Cleanup->setPlacementArg( + I, DominatingValue<RValue>::save(CGF, Arg.getRValue(CGF)), Arg.Ty); } CGF.initFullExprCleanup(); @@ -1678,15 +1702,21 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { llvm::Type *elementTy = ConvertTypeForMem(allocType); Address result = Builder.CreateElementBitCast(allocation, elementTy); - // Passing pointer through invariant.group.barrier to avoid propagation of + // Passing pointer through launder.invariant.group to avoid propagation of // vptrs information which may be included in previous type. // To not break LTO with different optimizations levels, we do it regardless // of optimization level. if (CGM.getCodeGenOpts().StrictVTablePointers && allocator->isReservedGlobalPlacementOperator()) - result = Address(Builder.CreateInvariantGroupBarrier(result.getPointer()), + result = Address(Builder.CreateLaunderInvariantGroup(result.getPointer()), result.getAlignment()); + // Emit sanitizer checks for pointer value now, so that in the case of an + // array it was checked only once and not at each constructor call. + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, + E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(), + result.getPointer(), allocType); + EmitNewInitializer(*this, E, allocType, elementTy, result, numElements, allocSizeWithoutCookie); if (E->isArray()) { @@ -1719,7 +1749,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { resultPtr = PHI; } - + return resultPtr; } @@ -1883,13 +1913,13 @@ static void EmitObjectDelete(CodeGenFunction &CGF, case Qualifiers::OCL_Strong: CGF.EmitARCDestroyStrong(Ptr, ARCPreciseLifetime); break; - + case Qualifiers::OCL_Weak: CGF.EmitARCDestroyWeak(Ptr); break; } } - + CGF.PopCleanupBlock(); } @@ -2092,9 +2122,9 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, } llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { - llvm::Type *StdTypeInfoPtrTy = + llvm::Type *StdTypeInfoPtrTy = ConvertType(E->getType())->getPointerTo(); - + if (E->isTypeOperand()) { llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext())); @@ -2107,7 +2137,7 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { // representing the type of the most derived object (that is, the dynamic // type) to which the glvalue refers. if (E->isPotentiallyEvaluated()) - return EmitTypeidFromVTable(*this, E->getExprOperand(), + return EmitTypeidFromVTable(*this, E->getExprOperand(), StdTypeInfoPtrTy); QualType OperandTy = E->getExprOperand()->getType(); @@ -2169,7 +2199,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, assert(SrcRecordTy->isRecordType() && "source type must be a record type!"); - // C++ [expr.dynamic.cast]p4: + // C++ [expr.dynamic.cast]p4: // If the value of v is a null pointer value in the pointer case, the result // is the null pointer value of type T. bool ShouldNullCheckSrcValue = @@ -2179,7 +2209,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr, llvm::BasicBlock *CastNull = nullptr; llvm::BasicBlock *CastNotNull = nullptr; llvm::BasicBlock *CastEnd = createBasicBlock("dynamic_cast.end"); - + if (ShouldNullCheckSrcValue) { CastNull = createBasicBlock("dynamic_cast.null"); CastNotNull = createBasicBlock("dynamic_cast.notnull"); |
