diff options
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 201 |
1 files changed, 157 insertions, 44 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index c7dc8337e19e0..3097caacb31c3 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -61,18 +61,30 @@ llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) { /// CreateTempAlloca - This creates a alloca and inserts it into the entry /// block. +Address CodeGenFunction::CreateTempAllocaWithoutCast(llvm::Type *Ty, + CharUnits Align, + const Twine &Name, + llvm::Value *ArraySize) { + auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); + Alloca->setAlignment(Align.getQuantity()); + return Address(Alloca, Align); +} + +/// CreateTempAlloca - This creates a alloca and inserts it into the entry +/// block. The alloca is casted to default address space if necessary. Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, const Twine &Name, llvm::Value *ArraySize, - bool CastToDefaultAddrSpace) { - auto Alloca = CreateTempAlloca(Ty, Name, ArraySize); - Alloca->setAlignment(Align.getQuantity()); - llvm::Value *V = Alloca; + Address *AllocaAddr) { + auto Alloca = CreateTempAllocaWithoutCast(Ty, Align, Name, ArraySize); + if (AllocaAddr) + *AllocaAddr = Alloca; + llvm::Value *V = Alloca.getPointer(); // Alloca always returns a pointer in alloca address space, which may // be different from the type defined by the language. For example, // in C++ the auto variables are in the default address space. Therefore // cast alloca to the default address space when necessary. - if (CastToDefaultAddrSpace && getASTAllocaAddressSpace() != LangAS::Default) { + if (getASTAllocaAddressSpace() != LangAS::Default) { auto DestAddrSpace = getContext().getTargetAddressSpace(LangAS::Default); llvm::IRBuilderBase::InsertPointGuard IPG(Builder); // When ArraySize is nullptr, alloca is inserted at AllocaInsertPt, @@ -125,17 +137,26 @@ Address CodeGenFunction::CreateIRTemp(QualType Ty, const Twine &Name) { } Address CodeGenFunction::CreateMemTemp(QualType Ty, const Twine &Name, - bool CastToDefaultAddrSpace) { + Address *Alloca) { // FIXME: Should we prefer the preferred type alignment here? - return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, - CastToDefaultAddrSpace); + return CreateMemTemp(Ty, getContext().getTypeAlignInChars(Ty), Name, Alloca); } Address CodeGenFunction::CreateMemTemp(QualType Ty, CharUnits Align, - const Twine &Name, - bool CastToDefaultAddrSpace) { - return CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, nullptr, - CastToDefaultAddrSpace); + const Twine &Name, Address *Alloca) { + return CreateTempAlloca(ConvertTypeForMem(Ty), Align, Name, + /*ArraySize=*/nullptr, Alloca); +} + +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, CharUnits Align, + const Twine &Name) { + return CreateTempAllocaWithoutCast(ConvertTypeForMem(Ty), Align, Name); +} + +Address CodeGenFunction::CreateMemTempWithoutCast(QualType Ty, + const Twine &Name) { + return CreateMemTempWithoutCast(Ty, getContext().getTypeAlignInChars(Ty), + Name); } /// EvaluateExprAsBool - Perform the usual unary conversions on the specified @@ -187,7 +208,7 @@ RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm_unreachable("bad evaluation kind"); } -/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will +/// EmitAnyExprToTemp - Similar to EmitAnyExpr(), however, the result will /// always be accessible even if no aggregate location is provided. RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) { AggValueSlot AggSlot = AggValueSlot::ignored(); @@ -214,7 +235,8 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E, EmitAggExpr(E, AggValueSlot::forAddr(Location, Quals, AggValueSlot::IsDestructed_t(IsInit), AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsAliased_t(!IsInit))); + AggValueSlot::IsAliased_t(!IsInit), + AggValueSlot::MayOverlap)); return; } @@ -347,7 +369,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, static Address createReferenceTemporary(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M, - const Expr *Inner) { + const Expr *Inner, + Address *Alloca = nullptr) { auto &TCG = CGF.getTargetHooks(); switch (M->getStorageDuration()) { case SD_FullExpression: @@ -380,7 +403,7 @@ static Address createReferenceTemporary(CodeGenFunction &CGF, return Address(C, alignment); } } - return CGF.CreateMemTemp(Ty, "ref.tmp"); + return CGF.CreateMemTemp(Ty, "ref.tmp", Alloca); } case SD_Thread: case SD_Static: @@ -432,7 +455,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { E->getType().getQualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, - AggValueSlot::IsNotAliased)); + AggValueSlot::IsNotAliased, + AggValueSlot::DoesNotOverlap)); break; } } @@ -456,7 +480,8 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { } // Create and initialize the reference temporary. - Address Object = createReferenceTemporary(*this, M, E); + Address Alloca = Address::invalid(); + Address Object = createReferenceTemporary(*this, M, E, &Alloca); if (auto *Var = dyn_cast<llvm::GlobalVariable>( Object.getPointer()->stripPointerCasts())) { Object = Address(llvm::ConstantExpr::getBitCast( @@ -475,13 +500,13 @@ EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *M) { case SD_Automatic: case SD_FullExpression: if (auto *Size = EmitLifetimeStart( - CGM.getDataLayout().getTypeAllocSize(Object.getElementType()), - Object.getPointer())) { + CGM.getDataLayout().getTypeAllocSize(Alloca.getElementType()), + Alloca.getPointer())) { if (M->getStorageDuration() == SD_Automatic) pushCleanupAfterFullExpr<CallLifetimeEnd>(NormalEHLifetimeMarker, - Object, Size); + Alloca, Size); else - pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Object, + pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, Alloca, Size); } break; @@ -873,7 +898,7 @@ static llvm::Value *getArrayIndexingBound( if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) return CGF.Builder.getInt(CAT->getSize()); else if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) - return CGF.getVLASize(VAT).first; + return CGF.getVLASize(VAT).NumElts; // Ignore pass_object_size here. It's not applicable on decayed pointers. } } @@ -1034,8 +1059,12 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, // Derived-to-base conversions. case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo, - TBAAInfo); + // TODO: Support accesses to members of base classes in TBAA. For now, we + // conservatively pretend that the complete object is of the base class + // type. + if (TBAAInfo) + *TBAAInfo = CGM.getTBAAAccessInfo(E->getType()); + Address Addr = EmitPointerWithAlignment(CE->getSubExpr(), BaseInfo); auto Derived = CE->getSubExpr()->getType()->getPointeeCXXRecordDecl(); return GetAddressOfBaseClass(Addr, Derived, CE->path_begin(), CE->path_end(), @@ -1785,7 +1814,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV) { return RValue::get(Vec); } -/// @brief Generates lvalue for partial ext_vector access. +/// Generates lvalue for partial ext_vector access. Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) { Address VectorAddress = LV.getExtVectorAddress(); const VectorType *ExprVT = LV.getType()->getAs<VectorType>(); @@ -1807,7 +1836,7 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) { return VectorBasePtrPlusIx; } -/// @brief Load of global gamed gegisters are always calls to intrinsics. +/// Load of global gamed gegisters are always calls to intrinsics. RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) { assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) && "Bad type for register variable"); @@ -2067,7 +2096,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, Dst.isVolatileQualified()); } -/// @brief Store of global named registers are always calls to intrinsics. +/// Store of global named registers are always calls to intrinsics. void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) { assert((Dst.getType()->isIntegerType() || Dst.getType()->isPointerType()) && "Bad type for register variable"); @@ -2206,6 +2235,22 @@ static LValue EmitThreadPrivateVarDeclLValue( return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); } +static Address emitDeclTargetLinkVarDeclLValue(CodeGenFunction &CGF, + const VarDecl *VD, QualType T) { + for (const auto *D : VD->redecls()) { + if (!VD->hasAttrs()) + continue; + if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>()) + if (Attr->getMapType() == OMPDeclareTargetDeclAttr::MT_Link) { + QualType PtrTy = CGF.getContext().getPointerType(VD->getType()); + Address Addr = + CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD); + return CGF.EmitLoadOfPointer(Addr, PtrTy->castAs<PointerType>()); + } + } + return Address::invalid(); +} + Address CodeGenFunction::EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo, @@ -2255,6 +2300,13 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, if (VD->getTLSKind() == VarDecl::TLS_Dynamic && CGF.CGM.getCXXABI().usesThreadWrapperFunction()) return CGF.CGM.getCXXABI().EmitThreadLocalVarDeclLValue(CGF, VD, T); + // Check if the variable is marked as declare target with link clause in + // device codegen. + if (CGF.getLangOpts().OpenMPIsDevice) { + Address Addr = emitDeclTargetLinkVarDeclLValue(CGF, VD, T); + if (Addr.isValid()) + return CGF.MakeAddrLValue(Addr, T, AlignmentSource::Decl); + } llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD); llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType()); @@ -2263,9 +2315,11 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, Address Addr(V, Alignment); // Emit reference to the private copy of the variable if it is an OpenMP // threadprivate variable. - if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>()) + if (CGF.getLangOpts().OpenMP && !CGF.getLangOpts().OpenMPSimd && + VD->hasAttr<OMPThreadPrivateDeclAttr>()) { return EmitThreadPrivateVarDeclLValue(CGF, VD, T, Addr, RealVarTy, E->getExprLoc()); + } LValue LV = VD->getType()->isReferenceType() ? CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(), AlignmentSource::Decl) : @@ -2446,7 +2500,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { // Check for OpenMP threadprivate variables. - if (getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { + if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd && + VD->hasAttr<OMPThreadPrivateDeclAttr>()) { return EmitThreadPrivateVarDeclLValue( *this, VD, T, addr, getTypes().ConvertTypeForMem(VD->getType()), E->getExprLoc()); @@ -2579,7 +2634,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) { StringRef NameItems[] = { PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName}; std::string GVName = llvm::join(NameItems, NameItems + 2, "."); - if (auto *BD = dyn_cast<BlockDecl>(CurCodeDecl)) { + if (auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl)) { std::string Name = SL->getString(); if (!Name.empty()) { unsigned Discriminator = @@ -2678,7 +2733,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) { return Builder.CreatePtrToInt(V, TargetTy); } -/// \brief Emit a representation of a SourceLocation for passing to a handler +/// Emit a representation of a SourceLocation for passing to a handler /// in a sanitizer runtime library. The format for this data is: /// \code /// struct SourceLocation { @@ -2737,7 +2792,7 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) { } namespace { -/// \brief Specify under what conditions this check can be recovered +/// Specify under what conditions this check can be recovered enum class CheckRecoverableKind { /// Always terminate program execution if this check fails. Unrecoverable, @@ -2945,6 +3000,7 @@ void CodeGenFunction::EmitCfiSlowPathCheck( bool WithDiag = !CGM.getCodeGenOpts().SanitizeTrap.has(Kind); llvm::CallInst *CheckCall; + llvm::Constant *SlowPathFn; if (WithDiag) { llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs); auto *InfoPtr = @@ -2953,20 +3009,20 @@ void CodeGenFunction::EmitCfiSlowPathCheck( InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr); - llvm::Constant *SlowPathDiagFn = CGM.getModule().getOrInsertFunction( + SlowPathFn = CGM.getModule().getOrInsertFunction( "__cfi_slowpath_diag", llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy}, false)); CheckCall = Builder.CreateCall( - SlowPathDiagFn, - {TypeId, Ptr, Builder.CreateBitCast(InfoPtr, Int8PtrTy)}); + SlowPathFn, {TypeId, Ptr, Builder.CreateBitCast(InfoPtr, Int8PtrTy)}); } else { - llvm::Constant *SlowPathFn = CGM.getModule().getOrInsertFunction( + SlowPathFn = CGM.getModule().getOrInsertFunction( "__cfi_slowpath", llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy}, false)); CheckCall = Builder.CreateCall(SlowPathFn, {TypeId, Ptr}); } + CGM.setDSOLocal(cast<llvm::GlobalValue>(SlowPathFn->stripPointerCasts())); CheckCall->setDoesNotThrow(); EmitBlock(Cont); @@ -2980,6 +3036,7 @@ void CodeGenFunction::EmitCfiCheckStub() { llvm::Function *F = llvm::Function::Create( llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy}, false), llvm::GlobalValue::WeakAnyLinkage, "__cfi_check", M); + CGM.setDSOLocal(F); llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", F); // FIXME: consider emitting an intrinsic call like // call void @llvm.cfi_check(i64 %0, i8* %1, i8* %2) @@ -3018,6 +3075,11 @@ void CodeGenFunction::EmitCfiCheckFail() { StartFunction(GlobalDecl(), CGM.getContext().VoidTy, F, FI, Args, SourceLocation()); + // This function should not be affected by blacklist. This function does + // not have a source location, but "src:*" would still apply. Revert any + // changes to SanOpts made in StartFunction. + SanOpts = CGM.getLangOpts().Sanitize; + llvm::Value *Data = EmitLoadOfScalar(GetAddrOfLocalVar(&ArgData), /*Volatile=*/false, CGM.getContext().VoidPtrTy, ArgData.getLocation()); @@ -3306,7 +3368,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, auto *Idx = EmitIdxAfterBase(/*Promote*/true); // The element count here is the total number of non-VLA elements. - llvm::Value *numElements = getVLASize(vla).first; + llvm::Value *numElements = getVLASize(vla).NumElts; // Effectively, the multiply by the VLA size is part of the GEP. // GEP indexes are signed, and scaling an index isn't permitted to @@ -3540,7 +3602,7 @@ LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy, VLA->getElementType(), IsLowerBound); // The element count here is the total number of non-VLA elements. - llvm::Value *NumElements = getVLASize(VLA).first; + llvm::Value *NumElements = getVLASize(VLA).NumElts; // Effectively, the multiply by the VLA size is part of the GEP. // GEP indexes are signed, and scaling an index isn't permitted to @@ -3808,6 +3870,18 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, } Address addr = base.getAddress(); + if (auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) { + if (CGM.getCodeGenOpts().StrictVTablePointers && + ClassDef->isDynamicClass()) { + // Getting to any field of dynamic object requires stripping dynamic + // information provided by invariant.group. This is because accessing + // fields may leak the real address of dynamic object, which could result + // in miscompilation when leaked pointer would be compared. + auto *stripped = Builder.CreateStripInvariantGroup(addr.getPointer()); + addr = Address(stripped, addr.getAlignment()); + } + } + unsigned RecordCVR = base.getVRQualifiers(); if (rec->isUnion()) { // For unions, there is no pointer adjustment. @@ -3816,7 +3890,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, hasAnyVptr(FieldType, getContext())) // Because unions can easily skip invariant.barriers, we need to add // a barrier every time CXXRecord field with vptr is referenced. - addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()), + addr = Address(Builder.CreateLaunderInvariantGroup(addr.getPointer()), addr.getAlignment()); } else { // For structs, we GEP to the field that the record layout suggests. @@ -4160,7 +4234,35 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) { assert(OpaqueValueMappingData::shouldBindAsLValue(e)); - return getOpaqueLValueMapping(e); + return getOrCreateOpaqueLValueMapping(e); +} + +LValue +CodeGenFunction::getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e) { + assert(OpaqueValueMapping::shouldBindAsLValue(e)); + + llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator + it = OpaqueLValues.find(e); + + if (it != OpaqueLValues.end()) + return it->second; + + assert(e->isUnique() && "LValue for a nonunique OVE hasn't been emitted"); + return EmitLValue(e->getSourceExpr()); +} + +RValue +CodeGenFunction::getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e) { + assert(!OpaqueValueMapping::shouldBindAsLValue(e)); + + llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator + it = OpaqueRValues.find(e); + + if (it != OpaqueRValues.end()) + return it->second; + + assert(e->isUnique() && "RValue for a nonunique OVE hasn't been emitted"); + return EmitAnyExpr(e->getSourceExpr()); } RValue CodeGenFunction::EmitRValueForField(LValue LV, @@ -4476,8 +4578,7 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee CalleeType = getContext().getCanonicalType(CalleeType); - const auto *FnType = - cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType()); + auto PointeeType = cast<PointerType>(CalleeType)->getPointeeType(); CGCallee Callee = OrigCallee; @@ -4486,8 +4587,12 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee if (llvm::Constant *PrefixSig = CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { SanitizerScope SanScope(this); + // Remove any (C++17) exception specifications, to allow calling e.g. a + // noexcept function through a non-noexcept pointer. + auto ProtoTy = + getContext().getFunctionTypeWithExceptionSpec(PointeeType, EST_None); llvm::Constant *FTRTTIConst = - CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true); + CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty}; llvm::StructType *PrefixStructTy = llvm::StructType::get( CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); @@ -4527,6 +4632,8 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee } } + const auto *FnType = cast<FunctionType>(PointeeType); + // If we are checking indirect calls and this call is indirect, check that the // function pointer is a member of the bit set for the function type. if (SanOpts.has(SanitizerKind::CFIICall) && @@ -4707,6 +4814,12 @@ static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF, // If this semantic expression is an opaque value, bind it // to the result of its source expression. if (const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) { + // Skip unique OVEs. + if (ov->isUnique()) { + assert(ov != resultExpr && + "A unique OVE cannot be used as the result expression"); + continue; + } // If this is the result expression, we may need to evaluate // directly into the slot. |