diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:11 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:11 +0000 |
commit | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (patch) | |
tree | 27425930fc0c91650a7f3527fcac8e0f92907b90 /lib/CodeGen | |
parent | 486754660bb926339aefcf012a3f848592babb8b (diff) | |
download | src-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.tar.gz src-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.zip |
Vendor import of clang trunk r338536:vendor/clang/clang-trunk-r338536
Notes
Notes:
svn path=/vendor/clang/dist/; revision=337139
svn path=/vendor/clang/clang-trunk-r338536/; revision=337140; tag=vendor/clang/clang-trunk-r338536
Diffstat (limited to 'lib/CodeGen')
42 files changed, 744 insertions, 591 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 617856a7b43e..8269b5b229a2 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -85,7 +85,7 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, cast<llvm::IntegerType>(CGM.getTypes().ConvertType(C.UnsignedLongTy)); llvm::PointerType *i8p = nullptr; if (CGM.getLangOpts().OpenCL) - i8p = + i8p = llvm::Type::getInt8PtrTy( CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant)); else @@ -117,7 +117,7 @@ static llvm::Constant *buildBlockDescriptor(CodeGenModule &CGM, CGM.getContext().getObjCEncodingForBlock(blockInfo.getBlockExpr()); elements.add(llvm::ConstantExpr::getBitCast( CGM.GetAddrOfConstantCString(typeAtEncoding).getPointer(), i8p)); - + // GC layout. if (C.getLangOpts().ObjC1) { if (CGM.getLangOpts().getGC() != LangOptions::NonGC) @@ -381,7 +381,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, else if (C.getLangOpts().ObjC1 && CGM.getLangOpts().getGC() == LangOptions::NonGC) info.HasCapturedVariableLayout = true; - + // Collect the layout chunks. SmallVector<BlockLayoutChunk, 16> layout; layout.reserve(block->capturesCXXThis() + @@ -487,12 +487,12 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, QualType VT = getCaptureFieldType(*CGF, CI); CharUnits size = C.getTypeSizeInChars(VT); CharUnits align = C.getDeclAlign(variable); - + maxFieldAlign = std::max(maxFieldAlign, align); llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(VT); - + layout.push_back( BlockLayoutChunk(align, size, lifetime, &CI, llvmType, VT)); } @@ -509,11 +509,11 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, // to get reproducible results. There should probably be an // llvm::array_pod_stable_sort. std::stable_sort(layout.begin(), layout.end()); - + // Needed for blocks layout info. info.BlockHeaderForcedGapOffset = info.BlockSize; info.BlockHeaderForcedGapSize = CharUnits::Zero(); - + CharUnits &blockSize = info.BlockSize; info.BlockAlign = std::max(maxFieldAlign, info.BlockAlign); @@ -564,7 +564,7 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, } assert(endAlign == getLowBit(blockSize)); - + // At this point, we just have to add padding if the end align still // isn't aligned right. if (endAlign < maxFieldAlign) { @@ -685,7 +685,7 @@ static void enterBlockScope(CodeGenFunction &CGF, BlockDecl *block) { CleanupKind cleanupKind = InactiveNormalCleanup; bool useArrayEHCleanup = CGF.needsEHCleanup(dtorKind); - if (useArrayEHCleanup) + if (useArrayEHCleanup) cleanupKind = InactiveNormalAndEHCleanup; CGF.pushDestroy(cleanupKind, addr, VT, @@ -1315,7 +1315,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, CurGD = GD; CurEHLocation = blockInfo.getBlockExpr()->getLocEnd(); - + BlockInfo = &blockInfo; // Arrange for local static and local extern declarations to appear @@ -1977,7 +1977,7 @@ public: // variable. llvm::Value *value = CGF.Builder.CreateLoad(srcField); - + llvm::Value *null = llvm::ConstantPointerNull::get(cast<llvm::PointerType>(value->getType())); @@ -2149,7 +2149,7 @@ generateByrefCopyHelper(CodeGenFunction &CGF, const BlockByrefInfo &byrefInfo, "src-object"); generator.emitCopy(CGF, destField, srcField); - } + } CGF.FinishFunction(); @@ -2321,7 +2321,7 @@ CodeGenFunction::buildByrefHelpers(llvm::StructType &byrefType, BlockFieldFlags flags; if (type->isBlockPointerType()) { flags |= BLOCK_FIELD_IS_BLOCK; - } else if (CGM.getContext().isObjCNSObjectType(type) || + } else if (CGM.getContext().isObjCNSObjectType(type) || type->isObjCObjectPointerType()) { flags |= BLOCK_FIELD_IS_OBJECT; } else { @@ -2380,24 +2380,24 @@ const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) { llvm::StructType *byrefType = llvm::StructType::create(getLLVMContext(), "struct.__block_byref_" + D->getNameAsString()); - + QualType Ty = D->getType(); CharUnits size; SmallVector<llvm::Type *, 8> types; - + // void *__isa; types.push_back(Int8PtrTy); size += getPointerSize(); - + // void *__forwarding; types.push_back(llvm::PointerType::getUnqual(byrefType)); size += getPointerSize(); - + // int32_t __flags; types.push_back(Int32Ty); size += CharUnits::fromQuantity(4); - + // int32_t __size; types.push_back(Int32Ty); size += CharUnits::fromQuantity(4); @@ -2408,7 +2408,7 @@ const BlockByrefInfo &CodeGenFunction::getBlockByrefInfo(const VarDecl *D) { /// void *__copy_helper; types.push_back(Int8PtrTy); size += getPointerSize(); - + /// void *__destroy_helper; types.push_back(Int8PtrTy); size += getPointerSize(); diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 5a8e960ffcc1..5abf82b3f6e1 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -70,7 +70,7 @@ public: BlockFlags() : flags(0) {} BlockFlags(BlockLiteralFlags flag) : flags(flag) {} BlockFlags(BlockByrefFlags flag) : flags(flag) {} - + uint32_t getBitMask() const { return flags; } bool empty() const { return flags == 0; } @@ -208,7 +208,7 @@ public: Capture v; v.Data = reinterpret_cast<uintptr_t>(value); return v; - } + } }; /// CanBeGlobal - True if the block can be global, i.e. it has @@ -226,13 +226,13 @@ public: /// UsesStret : True if the block uses an stret return. Mutable /// because it gets set later in the block-creation process. mutable bool UsesStret : 1; - + /// HasCapturedVariableLayout : True if block has captured variables /// and their layout meta-data has been generated. bool HasCapturedVariableLayout : 1; /// The mapping of allocated indexes within the block. - llvm::DenseMap<const VarDecl*, Capture> Captures; + llvm::DenseMap<const VarDecl*, Capture> Captures; Address LocalAddress; llvm::StructType *StructureType; @@ -241,7 +241,7 @@ public: CharUnits BlockSize; CharUnits BlockAlign; CharUnits CXXThisOffset; - + // Offset of the gap caused by block header having a smaller // alignment than the alignment of the block descriptor. This // is the gap offset before the first capturued field. diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h index d2e5eb256d3b..654ef72060b7 100644 --- a/lib/CodeGen/CGBuilder.h +++ b/lib/CodeGen/CGBuilder.h @@ -116,7 +116,7 @@ public: CharUnits Align, bool IsVolatile = false) { return CreateAlignedStore(Val, Addr, Align.getQuantity(), IsVolatile); } - + // FIXME: these "default-aligned" APIs should be removed, // but I don't feel like fixing all the builtin code right now. llvm::StoreInst *CreateDefaultAlignedStore(llvm::Value *Val, diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 0892e84a044c..e99121c46d9b 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -8848,7 +8848,7 @@ static Value *EmitX86Ternlog(CodeGenFunction &CGF, bool ZeroMask, return EmitX86Select(CGF, Ops[4], Ternlog, PassThru); } -static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, +static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, llvm::Type *DstTy) { unsigned NumberOfElements = DstTy->getVectorNumElements(); Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); @@ -9970,7 +9970,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Value *A = Builder.CreateExtractElement(Ops[0], (uint64_t)0); Function *F = CGM.getIntrinsic(Intrinsic::sqrt, A->getType()); A = Builder.CreateCall(F, {A}); - return Builder.CreateInsertElement(Ops[0], A, (uint64_t)0); + return Builder.CreateInsertElement(Ops[0], A, (uint64_t)0); } case X86::BI__builtin_ia32_sqrtsd_round_mask: case X86::BI__builtin_ia32_sqrtss_round_mask: { @@ -10282,7 +10282,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, return EmitX86MaskedCompareResult(*this, Cmp, NumElts, Ops[3]); } default: - return getVectorFCmpIR(Pred); + return getVectorFCmpIR(Pred); } } diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 475f17b77d92..d5945be43458 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -284,12 +284,12 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, /// indirect call to virtual functions. It makes the call through indexing /// into the vtable. CGCallee -CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, +CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD, NestedNameSpecifier *Qual, llvm::Type *Ty) { assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) && "BuildAppleKextVirtualCall - bad Qual kind"); - + const Type *QTy = Qual->getAsType(); QualType T = QualType(QTy, 0); const RecordType *RT = T->getAs<RecordType>(); diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp index 0611749acf17..3b1b47cdfe07 100644 --- a/lib/CodeGen/CGCXXABI.cpp +++ b/lib/CodeGen/CGCXXABI.cpp @@ -51,9 +51,9 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( ErrorUnsupportedABI(CGF, "calls through member pointers"); ThisPtrForCall = This.getPointer(); - const FunctionProtoType *FPT = + const FunctionProtoType *FPT = MPT->getPointeeType()->getAs<FunctionProtoType>(); - const CXXRecordDecl *RD = + const CXXRecordDecl *RD = cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl()); llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType( CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr)); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index f066ce168588..fa51dc30c58b 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -789,7 +789,7 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, bool erased = FunctionsBeingProcessed.erase(FI); (void)erased; assert(erased && "Not in set?"); - + return *FI; } @@ -1344,7 +1344,7 @@ static void CreateCoercedStore(llvm::Value *Src, } static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr, - const ABIArgInfo &info) { + const ABIArgInfo &info) { if (unsigned offset = info.getDirectOffset()) { addr = CGF.Builder.CreateElementBitCast(addr, CGF.Int8Ty); addr = CGF.Builder.CreateConstInBoundsByteGEP(addr, @@ -1675,7 +1675,7 @@ llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) { if (!isFuncTypeConvertible(FPT)) return llvm::StructType::get(getLLVMContext()); - + const CGFunctionInfo *Info; if (isa<CXXDestructorDecl>(MD)) Info = @@ -2683,7 +2683,7 @@ static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF, llvm::Value *retainedValue = retainCall->getArgOperand(0); llvm::LoadInst *load = dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts()); - if (!load || load->isAtomic() || load->isVolatile() || + if (!load || load->isAtomic() || load->isVolatile() || load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getPointer()) return nullptr; @@ -3139,7 +3139,7 @@ static void emitWriteback(CodeGenFunction &CGF, // Cast it back, in case we're writing an id to a Foo* or something. value = CGF.Builder.CreateBitCast(value, srcAddr.getElementType(), "icr.writeback-cast"); - + // Perform the writeback. // If we have a "to use" value, it's something we need to emit a use @@ -3245,7 +3245,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, // isn't null, so we need to register a dominating point so that the cleanups // system will make valid IR. CodeGenFunction::ConditionalEvaluation condEval(CGF); - + // Zero-initialize it if we're not doing a copy-initialization. bool shouldCopy = CRE->shouldCopy(); if (!shouldCopy) { @@ -3269,7 +3269,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr.getPointer(), "icr.isnull"); - finalArgument = CGF.Builder.CreateSelect(isNull, + finalArgument = CGF.Builder.CreateSelect(isNull, llvm::ConstantPointerNull::get(destType), temp.getPointer(), "icr.argument"); @@ -3309,7 +3309,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, valueToUse = src; } } - + // Finish the control flow if we needed it. if (shouldCopy && !provablyNonNull) { llvm::BasicBlock *copyBB = CGF.Builder.GetInsertBlock(); @@ -3360,7 +3360,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr; unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum; - // Prefer the nonnull attribute if it's present. + // Prefer the nonnull attribute if it's present. const NonNullAttr *NNAttr = nullptr; if (SanOpts.has(SanitizerKind::NonnullAttribute)) NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo); @@ -3713,7 +3713,7 @@ void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, getBundlesForFunclet(callee); if (getInvokeDest()) { - llvm::InvokeInst *invoke = + llvm::InvokeInst *invoke = Builder.CreateInvoke(callee, getUnreachableBlock(), getInvokeDest(), diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index 8adbe76fa6c3..99a36e4e12f1 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -356,7 +356,7 @@ public: class FunctionArgList : public SmallVector<const VarDecl*, 16> { }; - /// ReturnValueSlot - Contains the address where the return value of a + /// ReturnValueSlot - Contains the address where the return value of a /// function can be stored, and whether the address is volatile or not. class ReturnValueSlot { llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value; @@ -381,7 +381,7 @@ public: Address getValue() const { return Address(Value.getPointer(), Alignment); } bool isUnused() const { return Value.getInt() & IS_UNUSED; } }; - + } // end namespace CodeGen } // end namespace clang diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 0b9311f7771c..ec4eb000a3b9 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -655,7 +655,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, // the constructor. QualType::DestructionKind dtorKind = FieldType.isDestructedType(); if (CGF.needsEHCleanup(dtorKind)) - CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); + CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType); return; } } @@ -685,7 +685,10 @@ void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS, AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, - overlapForFieldInit(Field)); + overlapForFieldInit(Field), + AggValueSlot::IsNotZeroed, + // Checks are made by the code that calls constructor. + AggValueSlot::IsSanitizerChecked); EmitAggExpr(Init, Slot); break; } @@ -887,7 +890,7 @@ namespace { SanitizerSet OldSanOpts; }; } // end anonymous namespace - + namespace { class FieldMemcpyizer { public: @@ -1869,12 +1872,14 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, /// zero-initialized before it is constructed void CodeGenFunction::EmitCXXAggrConstructorCall( const CXXConstructorDecl *ctor, const ArrayType *arrayType, - Address arrayBegin, const CXXConstructExpr *E, bool zeroInitialize) { + Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked, + bool zeroInitialize) { QualType elementType; llvm::Value *numElements = emitArrayLength(arrayType, elementType, arrayBegin); - EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, zeroInitialize); + EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, + NewPointerIsChecked, zeroInitialize); } /// EmitCXXAggrConstructorCall - Emit a loop to call a particular @@ -1890,6 +1895,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, llvm::Value *numElements, Address arrayBase, const CXXConstructExpr *E, + bool NewPointerIsChecked, bool zeroInitialize) { // It's legal for numElements to be zero. This can happen both // dynamically, because x can be zero in 'new A[x]', and statically, @@ -1931,7 +1937,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, // The alignment of the base, adjusted by the size of a single element, // provides a conservative estimate of the alignment of every element. // (This assumes we never start tracking offsetted alignments.) - // + // // Note that these are complete objects and so we don't need to // use the non-virtual size or alignment. QualType type = getContext().getTypeDeclType(ctor->getParent()); @@ -1966,7 +1972,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false, /*Delegating=*/false, curAddr, E, - AggValueSlot::DoesNotOverlap); + AggValueSlot::DoesNotOverlap, NewPointerIsChecked); } // Go to the next element. @@ -2002,7 +2008,8 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E, - AggValueSlot::Overlap_t Overlap) { + AggValueSlot::Overlap_t Overlap, + bool NewPointerIsChecked) { CallArgList Args; // Push the this ptr. @@ -2031,7 +2038,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, /*ParamsToSkip*/ 0, Order); EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args, - Overlap, E->getExprLoc()); + Overlap, E->getExprLoc(), NewPointerIsChecked); } static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, @@ -2065,14 +2072,13 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, Address This, CallArgList &Args, AggValueSlot::Overlap_t Overlap, - SourceLocation Loc) { + SourceLocation Loc, + bool NewPointerIsChecked) { const CXXRecordDecl *ClassDecl = D->getParent(); - // C++11 [class.mfct.non-static]p2: - // If a non-static member function of a class X is called for an object that - // is not of type X, or of a type derived from X, the behavior is undefined. - EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, - This.getPointer(), getContext().getRecordType(ClassDecl)); + if (!NewPointerIsChecked) + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(), + getContext().getRecordType(ClassDecl), CharUnits::Zero()); if (D->isTrivial() && D->isDefaultConstructor()) { assert(Args.size() == 1 && "trivial default ctor with args"); @@ -2181,7 +2187,7 @@ void CodeGenFunction::EmitInheritedCXXConstructorCall( EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false, This, Args, AggValueSlot::MayOverlap, - E->getLocation()); + E->getLocation(), /*NewPointerIsChecked*/true); } void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall( @@ -2277,8 +2283,10 @@ CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(), /*ParamsToSkip*/ 1); - EmitCXXConstructorCall(D, Ctor_Complete, false, false, This, Args, - AggValueSlot::MayOverlap, E->getExprLoc()); + EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase*/false, + /*Delegating*/false, This, Args, + AggValueSlot::MayOverlap, E->getExprLoc(), + /*NewPointerIsChecked*/false); } void @@ -2314,7 +2322,8 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false, /*Delegating=*/true, This, DelegateArgs, - AggValueSlot::MayOverlap, Loc); + AggValueSlot::MayOverlap, Loc, + /*NewPointerIsChecked=*/true); } namespace { @@ -2346,7 +2355,10 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, - AggValueSlot::MayOverlap); + AggValueSlot::MayOverlap, + AggValueSlot::IsNotZeroed, + // Checks are made by the code that calls constructor. + AggValueSlot::IsSanitizerChecked); EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index cfd230997ed0..0a766d176200 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -319,7 +319,7 @@ static llvm::LoadInst *createLoadInstBefore(Address addr, const Twine &name, auto load = new llvm::LoadInst(addr.getPointer(), name, beforeInst); load->setAlignment(addr.getAlignment().getQuantity()); return load; -} +} /// All the branch fixups on the EH stack have propagated out past the /// outermost normal cleanup; resolve them all by adding cases to the @@ -621,7 +621,7 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, ++i; use.set(unreachableBB); - + // The only uses should be fixup switches. llvm::SwitchInst *si = cast<llvm::SwitchInst>(use.getUser()); if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) { @@ -640,7 +640,7 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, condition->eraseFromParent(); } } - + assert(entry->use_empty()); delete entry; } @@ -659,7 +659,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { Address NormalActiveFlag = Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag() : Address::invalid(); - Address EHActiveFlag = + Address EHActiveFlag = Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag() : Address::invalid(); @@ -708,7 +708,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // cleanup, rewrite it so that it leads to the appropriate place. if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) { llvm::BasicBlock *prebranchDest; - + // If the prebranch is semantically branching through the next // cleanup, just forward it to the next block, leaving the // insertion point in the prebranched block. @@ -922,7 +922,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { } // V. Set up the fallthrough edge out. - + // Case 1: a fallthrough source exists but doesn't branch to the // cleanup because the cleanup is inactive. if (!HasFallthrough && FallthroughSource) { @@ -1025,11 +1025,11 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { bool CodeGenFunction::isObviouslyBranchWithoutCleanups(JumpDest Dest) const { assert(Dest.getScopeDepth().encloses(EHStack.stable_begin()) && "stale jump destination"); - + // Calculate the innermost active normal cleanup. EHScopeStack::stable_iterator TopCleanup = EHStack.getInnermostActiveNormalCleanup(); - + // If we're not in an active normal cleanup scope, or if the // destination scope is within the innermost active normal cleanup // scope, we don't need to worry about fixups. @@ -1119,7 +1119,7 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { break; } } - + Builder.ClearInsertionPoint(); } diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h index 93be3e6c1502..15d6f46dcb56 100644 --- a/lib/CodeGen/CGCleanup.h +++ b/lib/CodeGen/CGCleanup.h @@ -509,7 +509,7 @@ class EHScopeStack::iterator { public: iterator() : Ptr(nullptr) {} - EHScope *get() const { + EHScope *get() const { return reinterpret_cast<EHScope*>(Ptr); } diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 097a1e043047..5be6fb3e4245 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -971,22 +971,27 @@ llvm::DIType *CGDebugInfo::CreateType(const BlockPointerType *Ty, auto *DescTy = DBuilder.createPointerType(EltTy, Size); FieldOffset = 0; - FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); - EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset)); - FType = CGM.getContext().IntTy; - EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset)); - EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset)); - FType = CGM.getContext().getPointerType(Ty->getPointeeType()); - EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset)); - - FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); - FieldSize = CGM.getContext().getTypeSize(Ty); - FieldAlign = CGM.getContext().getTypeAlign(Ty); - EltTys.push_back(DBuilder.createMemberType( - Unit, "__descriptor", nullptr, LineNo, FieldSize, FieldAlign, FieldOffset, - llvm::DINode::FlagZero, DescTy)); + if (CGM.getLangOpts().OpenCL) { + FType = CGM.getContext().IntTy; + EltTys.push_back(CreateMemberType(Unit, FType, "__size", &FieldOffset)); + EltTys.push_back(CreateMemberType(Unit, FType, "__align", &FieldOffset)); + } else { + FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); + EltTys.push_back(CreateMemberType(Unit, FType, "__isa", &FieldOffset)); + FType = CGM.getContext().IntTy; + EltTys.push_back(CreateMemberType(Unit, FType, "__flags", &FieldOffset)); + EltTys.push_back(CreateMemberType(Unit, FType, "__reserved", &FieldOffset)); + FType = CGM.getContext().getPointerType(Ty->getPointeeType()); + EltTys.push_back(CreateMemberType(Unit, FType, "__FuncPtr", &FieldOffset)); + FType = CGM.getContext().getPointerType(CGM.getContext().VoidTy); + FieldSize = CGM.getContext().getTypeSize(Ty); + FieldAlign = CGM.getContext().getTypeAlign(Ty); + EltTys.push_back(DBuilder.createMemberType( + Unit, "__descriptor", nullptr, LineNo, FieldSize, FieldAlign, FieldOffset, + llvm::DINode::FlagZero, DescTy)); + FieldOffset += FieldSize; + } - FieldOffset += FieldSize; Elements = DBuilder.getOrCreateArray(EltTys); // The __block_literal_generic structs are marked with a special @@ -3847,26 +3852,35 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, CGM.getDataLayout().getStructLayout(block.StructureType); SmallVector<llvm::Metadata *, 16> fields; - fields.push_back(createFieldType("__isa", C.VoidPtrTy, loc, AS_public, - blockLayout->getElementOffsetInBits(0), - tunit, tunit)); - fields.push_back(createFieldType("__flags", C.IntTy, loc, AS_public, - blockLayout->getElementOffsetInBits(1), - tunit, tunit)); - fields.push_back(createFieldType("__reserved", C.IntTy, loc, AS_public, - blockLayout->getElementOffsetInBits(2), - tunit, tunit)); - auto *FnTy = block.getBlockExpr()->getFunctionType(); - auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar()); - fields.push_back(createFieldType("__FuncPtr", FnPtrType, loc, AS_public, - blockLayout->getElementOffsetInBits(3), - tunit, tunit)); - fields.push_back(createFieldType( - "__descriptor", - C.getPointerType(block.NeedsCopyDispose - ? C.getBlockDescriptorExtendedType() - : C.getBlockDescriptorType()), - loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit)); + if (CGM.getLangOpts().OpenCL) { + fields.push_back(createFieldType("__size", C.IntTy, loc, AS_public, + blockLayout->getElementOffsetInBits(0), + tunit, tunit)); + fields.push_back(createFieldType("__align", C.IntTy, loc, AS_public, + blockLayout->getElementOffsetInBits(1), + tunit, tunit)); + } else { + fields.push_back(createFieldType("__isa", C.VoidPtrTy, loc, AS_public, + blockLayout->getElementOffsetInBits(0), + tunit, tunit)); + fields.push_back(createFieldType("__flags", C.IntTy, loc, AS_public, + blockLayout->getElementOffsetInBits(1), + tunit, tunit)); + fields.push_back(createFieldType("__reserved", C.IntTy, loc, AS_public, + blockLayout->getElementOffsetInBits(2), + tunit, tunit)); + auto *FnTy = block.getBlockExpr()->getFunctionType(); + auto FnPtrType = CGM.getContext().getPointerType(FnTy->desugar()); + fields.push_back(createFieldType("__FuncPtr", FnPtrType, loc, AS_public, + blockLayout->getElementOffsetInBits(3), + tunit, tunit)); + fields.push_back(createFieldType( + "__descriptor", + C.getPointerType(block.NeedsCopyDispose + ? C.getBlockDescriptorExtendedType() + : C.getBlockDescriptorType()), + loc, AS_public, blockLayout->getElementOffsetInBits(4), tunit, tunit)); + } // We want to sort the captures by offset, not because DWARF // requires this, but because we're paranoid about debuggers. diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 5e237d7e0b69..510863f68eff 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -27,9 +27,9 @@ using namespace CodeGen; static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress DeclPtr) { assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); - assert(!D.getType()->isReferenceType() && + assert(!D.getType()->isReferenceType() && "Should not call EmitDeclInit on a reference!"); - + QualType type = D.getType(); LValue lv = CGF.MakeAddrLValue(DeclPtr, type); @@ -67,7 +67,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, CodeGenModule &CGM = CGF.CGM; // FIXME: __attribute__((cleanup)) ? - + QualType type = D.getType(); QualType::DestructionKind dtorKind = type.isDestructedType(); @@ -219,7 +219,7 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD, CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, FI, FunctionArgList()); llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); - + // Make sure the call and the callee agree on calling convention. if (llvm::Function *dtorFn = dyn_cast<llvm::Function>(dtor->stripPointerCasts())) @@ -488,7 +488,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() { // Create our global initialization function. if (!PrioritizedCXXGlobalInits.empty()) { SmallVector<llvm::Function *, 8> LocalCXXGlobalInits; - llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), + llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), PrioritizedCXXGlobalInits.end()); // Iterate over "chunks" of ctors with same priority and emit each chunk // into separate function. Note - everything is sorted first by priority, @@ -684,8 +684,8 @@ llvm::Function *CodeGenFunction::generateDestroyHelper( StartFunction(VD, getContext().VoidTy, fn, FI, args); emitDestroy(addr, type, destroyer, useEHCleanupForArray); - + FinishFunction(); - + return fn; } diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index c9820c242554..a2ff102e1ab4 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -335,7 +335,7 @@ void CodeGenModule::SimplifyPersonality() { // Nothing to do if it's unused. if (!Fn || Fn->use_empty()) return; - + // Can't do the optimization if it has non-C++ uses. if (!PersonalityHasOnlyCXXUses(Fn)) return; @@ -443,7 +443,7 @@ void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E, void CodeGenFunction::EmitStartEHSpec(const Decl *D) { if (!CGM.getLangOpts().CXXExceptions) return; - + const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); if (!FD) { // Check if CapturedDecl is nothrow and create terminate scope for it. @@ -520,7 +520,7 @@ static void emitFilterDispatchBlock(CodeGenFunction &CGF, void CodeGenFunction::EmitEndEHSpec(const Decl *D) { if (!CGM.getLangOpts().CXXExceptions) return; - + const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D); if (!FD) { // Check if CapturedDecl is nothrow and pop terminate scope for it. @@ -1345,7 +1345,7 @@ namespace { CGF.PopCleanupBlock(); CGF.Builder.restoreIP(SavedIP); } - + // Now make sure we actually have an insertion point or the // cleanup gods will hate us. CGF.EnsureInsertPoint(); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 3097caacb31c..f168dd02ead1 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1820,14 +1820,14 @@ Address CodeGenFunction::EmitExtVectorElementLValue(LValue LV) { const VectorType *ExprVT = LV.getType()->getAs<VectorType>(); QualType EQT = ExprVT->getElementType(); llvm::Type *VectorElementTy = CGM.getTypes().ConvertType(EQT); - + Address CastToPointerElement = Builder.CreateElementBitCast(VectorAddress, VectorElementTy, "conv.ptr.element"); - + const llvm::Constant *Elts = LV.getExtVectorElts(); unsigned ix = getAccessedFieldNo(0, Elts); - + Address VectorBasePtrPlusIx = Builder.CreateConstInBoundsGEP(CastToPointerElement, ix, getContext().getTypeSizeInChars(EQT), @@ -3282,7 +3282,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, for (auto idx : indices.drop_back()) assert(isa<llvm::ConstantInt>(idx) && cast<llvm::ConstantInt>(idx)->isZero()); -#endif +#endif // Determine the element size of the statically-sized base. This is // the thing that the indices are expressed in terms of. @@ -3764,7 +3764,7 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field) { static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base, const FieldDecl *field) { const RecordDecl *rec = field->getParent(); - + unsigned idx = CGF.CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 291740478329..62641102861c 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -650,7 +650,7 @@ AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { EmitAggLoadOfLValue(E); return; } - + AggValueSlot Slot = EnsureSlot(E->getType()); CGF.EmitAggExpr(E->getInitializer(), Slot); } @@ -766,7 +766,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { AggValueSlot::DoesNotOverlap, AggValueSlot::IsZeroed); } - + CGF.EmitAggExpr(E->getSubExpr(), valueDest); return; } @@ -801,7 +801,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { "Implicit cast types must be compatible"); Visit(E->getSubExpr()); break; - + case CK_LValueBitCast: llvm_unreachable("should not be emitting lvalue bitcast as rvalue"); @@ -1140,7 +1140,7 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { Dest); return; } - + LValue LHS = CGF.EmitLValue(E->getLHS()); // If we have an atomic type, evaluate into the destination and then @@ -1155,7 +1155,7 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { // Codegen the RHS so that it stores directly into the LHS. AggValueSlot LHSSlot = - AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, + AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, needsGC(E->getLHS()->getType()), AggValueSlot::IsAliased, AggValueSlot::MayOverlap); @@ -1163,7 +1163,7 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { if (!LHSSlot.isVolatile() && CGF.hasVolatileMember(E->getLHS()->getType())) LHSSlot.setVolatile(true); - + CGF.EmitAggExpr(E->getRHS(), LHSSlot); // Copy into the destination if the assignment isn't ignored. @@ -1303,13 +1303,13 @@ static bool isSimpleZero(const Expr *E, CodeGenFunction &CGF) { // '\0' if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) return CL->getValue() == 0; - + // Otherwise, hard case: conservatively return false. return false; } -void +void AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) { QualType type = LV.getType(); // FIXME: Ignore result? @@ -1326,7 +1326,7 @@ AggExprEmitter::EmitInitializationToLValue(Expr *E, LValue LV) { RValue RV = CGF.EmitReferenceBindingToExpr(E); return CGF.EmitStoreThroughLValue(RV, LV); } - + switch (CGF.getEvaluationKind(type)) { case TEK_Complex: CGF.EmitComplexExprIntoLValue(E, LV, /*isInit*/ true); @@ -1357,7 +1357,7 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue lv) { // copied into it, we don't have to emit any zeros here. if (Dest.isZeroed() && CGF.getTypes().isZeroInitializable(type)) return; - + if (CGF.hasScalarEvaluationKind(type)) { // For non-aggregates, we can store the appropriate null constant. llvm::Value *null = CGF.CGM.EmitNullConstant(type); @@ -1501,12 +1501,12 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { if (curInitIndex == NumInitElements && Dest.isZeroed() && CGF.getTypes().isZeroInitializable(E->getType())) break; - + LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, field); // We never generate write-barries for initialized fields. LV.setNonGC(true); - + if (curInitIndex < NumInitElements) { // Store the initializer into the field. EmitInitializationToLValue(E->getInit(curInitIndex++), LV); @@ -1535,10 +1535,10 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { pushedCleanup = true; } } - + // If the GEP didn't get used because of a dead zero init or something // else, clean it up for -O0 builds and general tidiness. - if (!pushedCleanup && LV.isSimple()) + if (!pushedCleanup && LV.isSimple()) if (llvm::GetElementPtrInst *GEP = dyn_cast<llvm::GetElementPtrInst>(LV.getPointer())) if (GEP->use_empty()) @@ -1677,7 +1677,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { ILE = dyn_cast<InitListExpr>(ILE->getInit(0)); if (!ILE || !CGF.getTypes().isZeroInitializable(ILE->getType())) return CGF.getContext().getTypeSizeInChars(E->getType()); - + // InitListExprs for structs have to be handled carefully. If there are // reference members, we need to consider the size of the reference, not the // referencee. InitListExprs for unions and arrays can't have references. @@ -1685,7 +1685,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { if (!RT->isUnionType()) { RecordDecl *SD = E->getType()->getAs<RecordType>()->getDecl(); CharUnits NumNonZeroBytes = CharUnits::Zero(); - + unsigned ILEElement = 0; if (auto *CXXRD = dyn_cast<CXXRecordDecl>(SD)) while (ILEElement != CXXRD->getNumBases()) @@ -1701,7 +1701,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { continue; const Expr *E = ILE->getInit(ILEElement++); - + // Reference values are always non-null and have the width of a pointer. if (Field->getType()->isReferenceType()) NumNonZeroBytes += CGF.getContext().toCharUnitsFromBits( @@ -1709,12 +1709,12 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) { else NumNonZeroBytes += GetNumNonZeroBytesInInit(E, CGF); } - + return NumNonZeroBytes; } } - - + + CharUnits NumNonZeroBytes = CharUnits::Zero(); for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) NumNonZeroBytes += GetNumNonZeroBytesInInit(ILE->getInit(i), CGF); @@ -1750,14 +1750,14 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E, CharUnits NumNonZeroBytes = GetNumNonZeroBytesInInit(E, CGF); if (NumNonZeroBytes*4 > Size) return; - + // Okay, it seems like a good idea to use an initial memset, emit the call. llvm::Constant *SizeVal = CGF.Builder.getInt64(Size.getQuantity()); - Address Loc = Slot.getAddress(); + Address Loc = Slot.getAddress(); Loc = CGF.Builder.CreateElementBitCast(Loc, CGF.Int8Ty); CGF.Builder.CreateMemSet(Loc, CGF.Builder.getInt8(0), SizeVal, false); - + // Tell the AggExprEmitter that the slot is known zero. Slot.setZeroed(); } @@ -1777,7 +1777,7 @@ void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) { // Optimize the slot if possible. CheckAggExprForMemSetUse(Slot, E, *this); - + AggExprEmitter(*this, Slot, Slot.isIgnored()).Visit(const_cast<Expr*>(E)); } @@ -1826,7 +1826,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, if (getLangOpts().CPlusPlus) { if (const RecordType *RT = Ty->getAs<RecordType>()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl()); - assert((Record->hasTrivialCopyConstructor() || + assert((Record->hasTrivialCopyConstructor() || Record->hasTrivialCopyAssignment() || Record->hasTrivialMoveConstructor() || Record->hasTrivialMoveAssignment() || @@ -1899,7 +1899,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) { RecordDecl *Record = RecordTy->getDecl(); if (Record->hasObjectMember()) { - CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, SizeVal); return; } @@ -1907,7 +1907,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, QualType BaseType = getContext().getBaseElementType(Ty); if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) { if (RecordTy->getDecl()->hasObjectMember()) { - CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, + CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, SizeVal); return; } diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 8955d8a4a83c..f29ef754c03f 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -255,7 +255,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( 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); @@ -337,7 +337,7 @@ 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"); @@ -367,7 +367,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( } return RValue::get(nullptr); } - + CGCallee Callee; if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) { Callee = CGCallee::forDirect( @@ -416,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(), @@ -443,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. @@ -570,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 @@ -588,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. @@ -604,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 @@ -631,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.mayOverlap()); + Dest.getAddress(), E, Dest.mayOverlap(), + Dest.isSanitizerChecked()); } } @@ -642,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); @@ -709,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()); @@ -729,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 = @@ -820,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 @@ -897,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; @@ -954,7 +956,8 @@ static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, - MayOverlap); + MayOverlap, AggValueSlot::IsNotZeroed, + AggValueSlot::IsSanitizerChecked); CGF.EmitAggExpr(Init, Slot); return; } @@ -1024,7 +1027,9 @@ void CodeGenFunction::EmitNewArrayInitializer( AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, - AggValueSlot::DoesNotOverlap); + AggValueSlot::DoesNotOverlap, + AggValueSlot::IsNotZeroed, + AggValueSlot::IsSanitizerChecked); EmitAggExpr(ILE->getInit(0), Slot); // Move past these elements. @@ -1154,6 +1159,7 @@ void CodeGenFunction::EmitNewArrayInitializer( NumElements, llvm::ConstantInt::get(NumElements->getType(), InitListElements)); EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE, + /*NewPointerIsChecked*/true, CCE->requiresZeroInitialization()); return; } @@ -1230,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. @@ -1705,6 +1711,12 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { 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()) { @@ -1737,7 +1749,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { resultPtr = PHI; } - + return resultPtr; } @@ -1901,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(); } @@ -2110,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())); @@ -2125,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(); @@ -2187,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 = @@ -2197,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"); diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index cfd0b859233a..68766479a539 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -57,7 +57,7 @@ public: private: ConstStructBuilder(ConstantEmitter &emitter) - : CGM(emitter.CGM), Emitter(emitter), Packed(false), + : CGM(emitter.CGM), Emitter(emitter), Packed(false), NextFieldOffsetInChars(CharUnits::Zero()), LLVMStructAlignment(CharUnits::One()) { } @@ -244,11 +244,11 @@ void ConstStructBuilder::AppendBitField(const FieldDecl *Field, assert(AT->getElementType()->isIntegerTy(CharWidth) && AT->getNumElements() != 0 && "Expected non-empty array padding of undefs"); - + // Remove the padding array. NextFieldOffsetInChars -= CharUnits::fromQuantity(AT->getNumElements()); Elements.pop_back(); - + // Add the padding back in two chunks. AppendPadding(CharUnits::fromQuantity(AT->getNumElements()-1)); AppendPadding(CharUnits::One()); @@ -269,7 +269,7 @@ void ConstStructBuilder::AppendBitField(const FieldDecl *Field, if (CGM.getDataLayout().isBigEndian()) { // We want the high bits. - Tmp = + Tmp = FieldValue.lshr(FieldValue.getBitWidth() - CharWidth).trunc(CharWidth); } else { // We want the low bits. @@ -314,14 +314,14 @@ void ConstStructBuilder::AppendPadding(CharUnits PadSize) { llvm::Constant *C = llvm::UndefValue::get(Ty); Elements.push_back(C); - assert(getAlignment(C) == CharUnits::One() && + assert(getAlignment(C) == CharUnits::One() && "Padding must have 1 byte alignment!"); NextFieldOffsetInChars += getSizeInChars(C); } void ConstStructBuilder::AppendTailPadding(CharUnits RecordSize) { - assert(NextFieldOffsetInChars <= RecordSize && + assert(NextFieldOffsetInChars <= RecordSize && "Size mismatch!"); AppendPadding(RecordSize - NextFieldOffsetInChars); @@ -364,7 +364,7 @@ void ConstStructBuilder::ConvertStructToPacked() { LLVMStructAlignment = CharUnits::One(); Packed = true; } - + bool ConstStructBuilder::Build(InitListExpr *ILE) { RecordDecl *RD = ILE->getType()->getAs<RecordType>()->getDecl(); const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); @@ -972,7 +972,7 @@ public: unsigned NumInitElements = Updater->getNumInits(); unsigned NumElements = AType->getNumElements(); - + std::vector<llvm::Constant *> Elts; Elts.reserve(NumElements); @@ -1006,7 +1006,7 @@ public: Elts[i] = EmitDesignatedInitUpdater(Elts[i], ChildILE, destElemType); else Elts[i] = Emitter.tryEmitPrivateForMemory(Init, destElemType); - + if (!Elts[i]) return nullptr; RewriteType |= (Elts[i]->getType() != ElemType); @@ -1037,17 +1037,17 @@ public: auto C = Visit(E->getBase(), destType); if (!C) return nullptr; return EmitDesignatedInitUpdater(C, E->getUpdater(), destType); - } + } llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E, QualType Ty) { if (!E->getConstructor()->isTrivial()) return nullptr; // FIXME: We should not have to call getBaseElementType here. - const RecordType *RT = + const RecordType *RT = CGM.getContext().getBaseElementType(Ty)->getAs<RecordType>(); const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - + // If the class doesn't have a trivial destructor, we can't emit it as a // constant expr. if (!RD->hasTrivialDestructor()) @@ -1482,7 +1482,7 @@ llvm::Constant * ConstantEmitter::tryEmitAbstractForMemory(const Expr *E, QualType destType) { auto nonMemoryDestType = getNonMemoryType(CGM, destType); auto C = tryEmitAbstract(E, nonMemoryDestType); - return (C ? emitForMemory(C, destType) : nullptr); + return (C ? emitForMemory(C, destType) : nullptr); } llvm::Constant * @@ -1490,7 +1490,7 @@ ConstantEmitter::tryEmitAbstractForMemory(const APValue &value, QualType destType) { auto nonMemoryDestType = getNonMemoryType(CGM, destType); auto C = tryEmitAbstract(value, nonMemoryDestType); - return (C ? emitForMemory(C, destType) : nullptr); + return (C ? emitForMemory(C, destType) : nullptr); } llvm::Constant *ConstantEmitter::tryEmitPrivateForMemory(const Expr *E, @@ -2064,8 +2064,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, if (record->isUnion()) { if (Field->getIdentifier()) break; - if (const auto *FieldRD = - dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl())) + if (const auto *FieldRD = Field->getType()->getAsRecordDecl()) if (FieldRD->findFirstNamedDataMember()) break; } @@ -2074,7 +2073,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, // Fill in the virtual bases, if we're working with the complete object. if (CXXR && asCompleteObject) { for (const auto &I : CXXR->vbases()) { - const CXXRecordDecl *base = + const CXXRecordDecl *base = cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); // Ignore empty bases. @@ -2096,7 +2095,7 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM, if (!elements[i]) elements[i] = llvm::Constant::getNullValue(structure->getElementType(i)); } - + return llvm::ConstantStruct::get(structure, elements); } @@ -2126,7 +2125,7 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { if (getTypes().isZeroInitializable(T)) return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T)); - + if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) { llvm::ArrayType *ATy = cast<llvm::ArrayType>(getTypes().ConvertTypeForMem(T)); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 783f74c5026d..c62588c68272 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -299,13 +299,31 @@ public: Value *Src, QualType SrcType, QualType DstType, llvm::Type *DstTy, SourceLocation Loc); + /// Known implicit conversion check kinds. + /// Keep in sync with the enum of the same name in ubsan_handlers.h + enum ImplicitConversionCheckKind : unsigned char { + ICCK_IntegerTruncation = 0, + }; + + /// Emit a check that an [implicit] truncation of an integer does not + /// discard any bits. It is not UB, so we use the value after truncation. + void EmitIntegerTruncationCheck(Value *Src, QualType SrcType, Value *Dst, + QualType DstType, SourceLocation Loc); + /// Emit a conversion from the specified type to the specified destination /// type, both of which are LLVM scalar types. - Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, - SourceLocation Loc); + struct ScalarConversionOpts { + bool TreatBooleanAsSigned; + bool EmitImplicitIntegerTruncationChecks; - Value *EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, - SourceLocation Loc, bool TreatBooleanAsSigned); + ScalarConversionOpts() + : TreatBooleanAsSigned(false), + EmitImplicitIntegerTruncationChecks(false) {} + }; + Value * + EmitScalarConversion(Value *Src, QualType SrcTy, QualType DstTy, + SourceLocation Loc, + ScalarConversionOpts Opts = ScalarConversionOpts()); /// Emit a conversion from the specified complex type to the specified /// destination type, where the destination type is an LLVM scalar type. @@ -923,18 +941,59 @@ void ScalarExprEmitter::EmitFloatConversionCheck( SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc); } -/// Emit a conversion from the specified type to the specified destination type, -/// both of which are LLVM scalar types. -Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, - QualType DstType, - SourceLocation Loc) { - return EmitScalarConversion(Src, SrcType, DstType, Loc, false); +void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, + Value *Dst, QualType DstType, + SourceLocation Loc) { + if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerTruncation)) + return; + + llvm::Type *SrcTy = Src->getType(); + llvm::Type *DstTy = Dst->getType(); + + // We only care about int->int conversions here. + // We ignore conversions to/from pointer and/or bool. + if (!(SrcType->isIntegerType() && DstType->isIntegerType())) + return; + + assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && + "clang integer type lowered to non-integer llvm type"); + + unsigned SrcBits = SrcTy->getScalarSizeInBits(); + unsigned DstBits = DstTy->getScalarSizeInBits(); + // This must be truncation. Else we do not care. + if (SrcBits <= DstBits) + return; + + assert(!DstType->isBooleanType() && "we should not get here with booleans."); + + CodeGenFunction::SanitizerScope SanScope(&CGF); + + llvm::Value *Check = nullptr; + + // 1. Extend the truncated value back to the same width as the Src. + bool InputSigned = DstType->isSignedIntegerOrEnumerationType(); + Check = Builder.CreateIntCast(Dst, SrcTy, InputSigned, "anyext"); + // 2. Equality-compare with the original source value + Check = Builder.CreateICmpEQ(Check, Src, "truncheck"); + // If the comparison result is 'i1 false', then the truncation was lossy. + + llvm::Constant *StaticArgs[] = { + CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), + CGF.EmitCheckTypeDescriptor(DstType), + llvm::ConstantInt::get(Builder.getInt8Ty(), ICCK_IntegerTruncation)}; + CGF.EmitCheck(std::make_pair(Check, SanitizerKind::ImplicitIntegerTruncation), + SanitizerHandler::ImplicitConversion, StaticArgs, {Src, Dst}); } +/// Emit a conversion from the specified type to the specified destination type, +/// both of which are LLVM scalar types. Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, QualType DstType, SourceLocation Loc, - bool TreatBooleanAsSigned) { + ScalarConversionOpts Opts) { + QualType NoncanonicalSrcType = SrcType; + QualType NoncanonicalDstType = DstType; + SrcType = CGF.getContext().getCanonicalType(SrcType); DstType = CGF.getContext().getCanonicalType(DstType); if (SrcType == DstType) return Src; @@ -1083,7 +1142,7 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, if (isa<llvm::IntegerType>(SrcTy)) { bool InputSigned = SrcType->isSignedIntegerOrEnumerationType(); - if (SrcType->isBooleanType() && TreatBooleanAsSigned) { + if (SrcType->isBooleanType() && Opts.TreatBooleanAsSigned) { InputSigned = true; } if (isa<llvm::IntegerType>(DstTy)) @@ -1118,6 +1177,10 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, } } + if (Opts.EmitImplicitIntegerTruncationChecks) + EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res, + NoncanonicalDstType, Loc); + return Res; } @@ -1812,16 +1875,26 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { return Builder.CreateVectorSplat(NumElements, Elt, "splat"); } - case CK_IntegralCast: + case CK_IntegralCast: { + ScalarConversionOpts Opts; + if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerTruncation)) { + if (auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) + Opts.EmitImplicitIntegerTruncationChecks = !ICE->isPartOfExplicitCast(); + } + return EmitScalarConversion(Visit(E), E->getType(), DestTy, + CE->getExprLoc(), Opts); + } case CK_IntegralToFloating: case CK_FloatingToIntegral: case CK_FloatingCast: return EmitScalarConversion(Visit(E), E->getType(), DestTy, CE->getExprLoc()); - case CK_BooleanToSignedIntegral: + case CK_BooleanToSignedIntegral: { + ScalarConversionOpts Opts; + Opts.TreatBooleanAsSigned = true; return EmitScalarConversion(Visit(E), E->getType(), DestTy, - CE->getExprLoc(), - /*TreatBooleanAsSigned=*/true); + CE->getExprLoc(), Opts); + } case CK_IntegralToBoolean: return EmitIntToBoolConversion(Visit(E)); case CK_PointerToBoolean: @@ -2766,7 +2839,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, // if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(), op.Opcode, - expr->getLHS(), + expr->getLHS(), expr->getRHS())) return CGF.Builder.CreateIntToPtr(index, pointer->getType()); diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp index 28998ce8db44..21e2b8dd8c31 100644 --- a/lib/CodeGen/CGLoopInfo.cpp +++ b/lib/CodeGen/CGLoopInfo.cpp @@ -155,7 +155,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, unsigned ValueInt = 1; // Translate opencl_unroll_hint attribute argument to // equivalent LoopHintAttr enums. - // OpenCL v2.0 s6.11.5: + // OpenCL v2.0 s6.11.5: // 0 - full unroll (no argument). // 1 - disable unroll. // other positive integer n - unroll by n. diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 81c1201c0e06..b94bbf2a384f 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -45,7 +45,7 @@ static llvm::Constant *getNullForVariable(Address addr) { /// Emits an instance of NSConstantString representing the object. llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) { - llvm::Constant *C = + llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(E->getString()).getPointer(); // FIXME: This bitcast should just be made an invariant on the Runtime. return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); @@ -65,7 +65,7 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { assert(BoxingMethod && "BoxingMethod is null"); assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method"); Selector Sel = BoxingMethod->getSelector(); - + // Generate a reference to the class pointer, which will be the receiver. // Assumes that the method was introduced in the class that should be // messaged (avoids pulling it out of the result type). @@ -76,8 +76,8 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { CallArgList Args; const ParmVarDecl *ArgDecl = *BoxingMethod->param_begin(); QualType ArgQT = ArgDecl->getType().getUnqualifiedType(); - - // ObjCBoxedExpr supports boxing of structs and unions + + // ObjCBoxedExpr supports boxing of structs and unions // via [NSValue valueWithBytes:objCType:] const QualType ValueType(SubExpr->getType().getCanonicalType()); if (ValueType->isObjCBoxableRecordType()) { @@ -92,7 +92,7 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { std::string Str; getContext().getObjCEncodingForType(ValueType, Str); llvm::Constant *GV = CGM.GetAddrOfConstantCString(Str).getPointer(); - + // Cast type encoding to correct type const ParmVarDecl *EncodingDecl = BoxingMethod->parameters()[1]; QualType EncodingQT = EncodingDecl->getType().getUnqualifiedType(); @@ -106,7 +106,7 @@ CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) { RValue result = Runtime.GenerateMessageSend( *this, ReturnValueSlot(), BoxingMethod->getReturnType(), Sel, Receiver, Args, ClassDecl, BoxingMethod); - return Builder.CreateBitCast(result.getScalarVal(), + return Builder.CreateBitCast(result.getScalarVal(), ConvertType(E->getType())); } @@ -119,7 +119,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, DLE = cast<ObjCDictionaryLiteral>(E); // Optimize empty collections by referencing constants, when available. - uint64_t NumElements = + uint64_t NumElements = ALE ? ALE->getNumElements() : DLE->getNumElements(); if (NumElements == 0 && CGM.getLangOpts().ObjCRuntime.hasEmptyCollections()) { StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__"; @@ -138,8 +138,8 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()), NumElements); QualType ElementType = Context.getObjCIdType().withConst(); - QualType ElementArrayType - = Context.getConstantArrayType(ElementType, APNumElements, + QualType ElementArrayType + = Context.getConstantArrayType(ElementType, APNumElements, ArrayType::Normal, /*IndexTypeQuals=*/0); // Allocate the temporary array(s). @@ -147,7 +147,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, Address Keys = Address::invalid(); if (DLE) Keys = CreateMemTemp(ElementArrayType, "keys"); - + // In ARC, we may need to do extra work to keep all the keys and // values alive until after the call. SmallVector<llvm::Value *, 16> NeededObjects; @@ -169,7 +169,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, if (TrackNeededObjects) { NeededObjects.push_back(value); } - } else { + } else { // Emit the key and store it to the appropriate array slot. const Expr *Key = DLE->getKeyValueElement(i).Key; LValue KeyLV = MakeAddrLValue( @@ -191,9 +191,9 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, } } } - + // Generate the argument list. - CallArgList Args; + CallArgList Args; ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin(); const ParmVarDecl *argDecl = *PI++; QualType ArgQT = argDecl->getType().getUnqualifiedType(); @@ -205,7 +205,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, } argDecl = *PI; ArgQT = argDecl->getType().getUnqualifiedType(); - llvm::Value *Count = + llvm::Value *Count = llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements); Args.add(RValue::get(Count), ArgQT); @@ -214,7 +214,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, QualType ResultType = E->getType(); const ObjCObjectPointerType *InterfacePointerType = ResultType->getAsObjCInterfacePointerType(); - ObjCInterfaceDecl *Class + ObjCInterfaceDecl *Class = InterfacePointerType->getObjectType()->getInterface(); CGObjCRuntime &Runtime = CGM.getObjCRuntime(); llvm::Value *Receiver = Runtime.GetClass(*this, Class); @@ -232,7 +232,7 @@ llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E, EmitARCIntrinsicUse(NeededObjects); } - return Builder.CreateBitCast(result.getScalarVal(), + return Builder.CreateBitCast(result.getScalarVal(), ConvertType(E->getType())); } @@ -557,7 +557,7 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD, if (CGM.getLangOpts().ObjCAutoRefCount && OMD->isInstanceMethod() && OMD->getSelector().isUnarySelector()) { - const IdentifierInfo *ident = + const IdentifierInfo *ident = OMD->getSelector().getIdentifierInfoForSlot(0); if (ident->isStr("dealloc")) EHStack.pushCleanup<FinishARCDealloc>(getARCCleanupKind()); @@ -580,7 +580,7 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { /// emitStructGetterCall - Call the runtime function to load a property /// into the return value slot. -static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, +static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, bool isAtomic, bool hasStrong) { ASTContext &Context = CGF.getContext(); @@ -588,7 +588,7 @@ static void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar, CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0) .getAddress(); - // objc_copyStruct (ReturnValue, &structIvar, + // objc_copyStruct (ReturnValue, &structIvar, // sizeof (Type of Ivar), isAtomic, false); CallArgList args; @@ -844,30 +844,30 @@ static bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) { return false; } -/// emitCPPObjectAtomicGetterCall - Call the runtime function to +/// emitCPPObjectAtomicGetterCall - Call the runtime function to /// copy the ivar into the resturn slot. -static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, +static void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF, llvm::Value *returnAddr, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn) { // objc_copyCppObjectAtomic (&returnSlot, &CppObjectIvar, // AtomicHelperFn); CallArgList args; - + // The 1st argument is the return Slot. args.add(RValue::get(returnAddr), CGF.getContext().VoidPtrTy); - + // The 2nd argument is the address of the ivar. - llvm::Value *ivarAddr = - CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), + llvm::Value *ivarAddr = + CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0).getPointer(); ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy); args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy); - + // Third argument is the helper function. args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy); - - llvm::Constant *copyCppAtomicObjectFn = + + llvm::Constant *copyCppAtomicObjectFn = CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction(); CGCallee callee = CGCallee::forDirect(copyCppAtomicObjectFn); CGF.EmitCall( @@ -889,7 +889,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, } else { ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); - emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), + emitCPPObjectAtomicGetterCall(*this, ReturnValue.getPointer(), ivar, AtomicHelperFn); } return; @@ -899,7 +899,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, QualType propType = prop->getType(); ObjCMethodDecl *getterMethod = prop->getGetterMethodDecl(); - ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); + ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); // Pick an implementation strategy. PropertyImplStrategy strategy(CGM, propImpl); @@ -1039,7 +1039,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, value = Builder.CreateBitCast( value, ConvertType(GetterMethodDecl->getReturnType())); } - + EmitReturnOfRValue(RValue::get(value), propType); return; } @@ -1055,7 +1055,7 @@ CodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl, /// from the first formal parameter into the given ivar. static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar) { - // objc_copyStruct (&structIvar, &Arg, + // objc_copyStruct (&structIvar, &Arg, // sizeof (struct something), true, false); CallArgList args; @@ -1068,7 +1068,7 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, // The second argument is the address of the parameter variable. ParmVarDecl *argVar = *OMD->param_begin(); - DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), + DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), VK_LValue, SourceLocation()); llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer(); argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy); @@ -1093,36 +1093,36 @@ static void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, callee, ReturnValueSlot(), args); } -/// emitCPPObjectAtomicSetterCall - Call the runtime function to store -/// the value from the first formal parameter into the given ivar, using +/// emitCPPObjectAtomicSetterCall - Call the runtime function to store +/// the value from the first formal parameter into the given ivar, using /// the Cpp API for atomic Cpp objects with non-trivial copy assignment. -static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, +static void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD, ObjCIvarDecl *ivar, llvm::Constant *AtomicHelperFn) { - // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg, + // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg, // AtomicHelperFn); CallArgList args; - + // The first argument is the address of the ivar. - llvm::Value *ivarAddr = - CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), + llvm::Value *ivarAddr = + CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(), ivar, 0).getPointer(); ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy); args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy); - + // The second argument is the address of the parameter variable. ParmVarDecl *argVar = *OMD->param_begin(); - DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), + DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(), VK_LValue, SourceLocation()); llvm::Value *argAddr = CGF.EmitLValue(&argRef).getPointer(); argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy); args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy); - + // Third argument is the helper function. args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy); - - llvm::Constant *fn = + + llvm::Constant *fn = CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction(); CGCallee callee = CGCallee::forDirect(fn); CGF.EmitCall( @@ -1168,7 +1168,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, const ObjCPropertyDecl *prop = propImpl->getPropertyDecl(); ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl(); ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl(); - + // Just use the setter expression if Sema gave us one and it's // non-trivial. if (!hasTrivialSetExpr(propImpl)) { @@ -1221,7 +1221,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, llvm::Constant *setPropertyFn = nullptr; if (UseOptimizedSetter(CGM)) { // 10.8 and iOS 6.0 code and GC is off - setOptimizedPropertyFn = + setOptimizedPropertyFn = CGM.getObjCRuntime() .GetOptimizedPropertySetFunction(strategy.isAtomic(), strategy.isCopy()); @@ -1237,7 +1237,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, return; } } - + // Emit objc_setProperty((id) self, _cmd, offset, arg, // <is-atomic>, <is-copy>). llvm::Value *cmd = @@ -1272,7 +1272,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, EmitCall(getTypes().arrangeBuiltinFunctionCall(getContext().VoidTy, args), callee, ReturnValueSlot(), args); } - + return; } @@ -1301,7 +1301,7 @@ CodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl, ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack, argType.getUnqualifiedType(), CK_LValueToRValue, &arg, VK_RValue); - + // The property type can differ from the ivar type in some situations with // Objective-C pointer types, we can always bit cast the RHS in these cases. // The following absurdity is just to ensure well-formed IR. @@ -1435,7 +1435,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, for (const auto *IvarInit : IMP->inits()) { FieldDecl *Field = IvarInit->getAnyMember(); ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); - LValue LV = EmitLValueForIvar(TypeOfSelfObject(), + LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed, @@ -2015,7 +2015,7 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) { } else if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0) { llvm::FunctionType *type = llvm::FunctionType::get(CGF.VoidTy, /*variadic*/false); - + marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true); // If we're at -O1 and above, we don't want to litter the code @@ -2368,10 +2368,10 @@ llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { IdentifierInfo *II = &CGM.getContext().Idents.get("alloc"); Selector AllocSel = getContext().Selectors.getSelector(0, &II); CallArgList Args; - RValue AllocRV = - Runtime.GenerateMessageSend(*this, ReturnValueSlot(), + RValue AllocRV = + Runtime.GenerateMessageSend(*this, ReturnValueSlot(), getContext().getObjCIdType(), - AllocSel, Receiver, Args); + AllocSel, Receiver, Args); // [Receiver init] Receiver = AllocRV.getScalarVal(); @@ -2380,7 +2380,7 @@ llvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() { RValue InitRV = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), getContext().getObjCIdType(), - InitSel, Receiver, Args); + InitSel, Receiver, Args); return InitRV.getScalarVal(); } @@ -2391,7 +2391,7 @@ void CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) { Selector DrainSel = getContext().Selectors.getSelector(0, &II); CallArgList Args; CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), - getContext().VoidTy, DrainSel, Arg, Args); + getContext().VoidTy, DrainSel, Arg, Args); } void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF, @@ -2471,7 +2471,7 @@ static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, e = e->IgnoreParens(); QualType type = e->getType(); - // If we're loading retained from a __strong xvalue, we can avoid + // If we're loading retained from a __strong xvalue, we can avoid // an extra retain/release pair by zeroing out the source of this // "move" operation. if (e->isXValue() && @@ -2479,14 +2479,14 @@ static TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF, type.getObjCLifetime() == Qualifiers::OCL_Strong) { // Emit the lvalue. LValue lv = CGF.EmitLValue(e); - + // Load the object pointer. llvm::Value *result = CGF.EmitLoadOfLValue(lv, SourceLocation()).getScalarVal(); - + // Set the source pointer to NULL. CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv); - + return TryEmitResult(result, true); } @@ -3225,7 +3225,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null"); if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty))) return HelperFn; - + ASTContext &C = getContext(); IdentifierInfo *II = &CGM.getContext().Idents.get("__assign_helper_atomic_property_"); @@ -3241,7 +3241,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( QualType SrcTy = Ty; SrcTy.addConst(); SrcTy = C.getPointerType(SrcTy); - + FunctionArgList args; ImplicitParamDecl DstDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr, DestTy, ImplicitParamDecl::Other); @@ -3254,7 +3254,7 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args); llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); - + llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, "__assign_helper_atomic_property_", @@ -3263,23 +3263,23 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); - + DeclRefExpr DstExpr(&DstDecl, false, DestTy, VK_RValue, SourceLocation()); UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(), VK_LValue, OK_Ordinary, SourceLocation(), false); - + DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, SourceLocation(), false); - + Expr *Args[2] = { &DST, &SRC }; CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment()); CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(), VK_LValue, SourceLocation(), FPOptions()); - + EmitStmt(&TheCall); FinishFunction(); @@ -3307,8 +3307,8 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null"); if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty))) return HelperFn; - - + + ASTContext &C = getContext(); IdentifierInfo *II = &CGM.getContext().Idents.get("__copy_helper_atomic_property_"); @@ -3324,7 +3324,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( QualType SrcTy = Ty; SrcTy.addConst(); SrcTy = C.getPointerType(SrcTy); - + FunctionArgList args; ImplicitParamDecl DstDecl(getContext(), FD, SourceLocation(), /*Id=*/nullptr, DestTy, ImplicitParamDecl::Other); @@ -3337,7 +3337,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, args); llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI); - + llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, "__copy_helper_atomic_property_", &CGM.getModule()); @@ -3345,16 +3345,16 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); StartFunction(FD, C.VoidTy, Fn, FI, args); - + DeclRefExpr SrcExpr(&SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); - + UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, SourceLocation(), false); - - CXXConstructExpr *CXXConstExpr = + + CXXConstructExpr *CXXConstExpr = cast<CXXConstructExpr>(PID->getGetterCXXConstructor()); - + SmallVector<Expr*, 4> ConstructorArgs; ConstructorArgs.push_back(&SRC); ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()), @@ -3371,21 +3371,21 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( CXXConstExpr->requiresZeroInitialization(), CXXConstExpr->getConstructionKind(), SourceRange()); - + DeclRefExpr DstExpr(&DstDecl, false, DestTy, VK_RValue, SourceLocation()); - + RValue DV = EmitAnyExpr(&DstExpr); CharUnits Alignment = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType()); - EmitAggExpr(TheCXXConstructExpr, + EmitAggExpr(TheCXXConstructExpr, AggValueSlot::forAddr(Address(DV.getScalarVal(), Alignment), Qualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, AggValueSlot::DoesNotOverlap)); - + FinishFunction(); HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy); CGM.setAtomicGetterHelperFnMap(Ty, HelperFn); diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 6a0554b46b1c..3e994edc976b 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -114,7 +114,7 @@ protected: /// contains the receiver (object) and the expected class. llvm::StructType *ObjCSuperTy; /// struct objc_super*. The type of the argument to the superclass message - /// lookup functions. + /// lookup functions. llvm::PointerType *PtrToObjCSuperTy; /// LLVM type for selectors. Opaque pointer (i8*) unless a header declaring /// SEL is included in a header somewhere, in which case it will be whatever @@ -159,7 +159,7 @@ protected: llvm::IntegerType *LongTy; /// LLVM type for C size_t. Used in various runtime data structures. llvm::IntegerType *SizeTy; - /// LLVM type for C intptr_t. + /// LLVM type for C intptr_t. llvm::IntegerType *IntPtrTy; /// LLVM type for C ptrdiff_t. Mainly used in property accessor functions. llvm::IntegerType *PtrDiffTy; @@ -197,7 +197,7 @@ protected: /// Helper function that generates a constant string and returns a pointer to /// the start of the string. The result of this function can be used anywhere - /// where the C code specifies const char*. + /// where the C code specifies const char*. llvm::Constant *MakeConstantString(StringRef Str, const char *Name = "") { ConstantAddress Array = CGM.GetAddrOfConstantCString(Str, Name); return llvm::ConstantExpr::getGetElementPtr(Array.getElementType(), @@ -243,7 +243,7 @@ protected: return MakeConstantString(PD->getNameAsString()); } - /// Push the property attributes into two structure fields. + /// Push the property attributes into two structure fields. void PushPropertyAttributes(ConstantStructBuilder &Fields, const ObjCPropertyDecl *property, bool isSynthesized=true, bool isDynamic=true) { @@ -377,7 +377,7 @@ protected: /// Runtime functions used for memory management in GC mode. Note that clang /// supports code generation for calling these functions, but neither GNU /// runtime actually supports this API properly yet. - LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, + LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn, WeakAssignFn, GlobalAssignFn; typedef std::pair<std::string, std::string> ClassAliasPair; @@ -554,7 +554,7 @@ protected: /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 /// bits set to their values, LSB first, while larger ones are stored in a /// structure of this / form: - /// + /// /// struct { int32_t length; int32_t values[length]; }; /// /// The values in the array are stored in host-endian format, with the least @@ -810,7 +810,7 @@ class CGObjCGNUstep : public CGObjCGNU { // Slot_t objc_slot_lookup_super(struct objc_super*, SEL); SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy, PtrToObjCSuperTy, SelectorTy); - // If we're in ObjC++ mode, then we want to make + // If we're in ObjC++ mode, then we want to make if (CGM.getLangOpts().CPlusPlus) { llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext); // void *__cxa_begin_catch(void *e) @@ -892,7 +892,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { static constexpr const char *const SelSection = "__objc_selectors"; /// The section for classes. static constexpr const char *const ClsSection = "__objc_classes"; - /// The section for references to classes. + /// The section for references to classes. static constexpr const char *const ClsRefSection = "__objc_class_refs"; /// The section for categories. static constexpr const char *const CatSection = "__objc_cats"; @@ -956,8 +956,8 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { bool isNonASCII = SL->containsNonAscii(); - auto LiteralLength = SL->getLength(); - + auto LiteralLength = SL->getLength(); + if ((CGM.getTarget().getPointerWidth(0) == 64) && (LiteralLength < 9) && !isNonASCII) { // Tiny strings are only used on 64-bit platforms. They store 8 7-bit @@ -1224,7 +1224,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { std::string Name = SymbolForProtocol(ProtocolName); auto *GV = TheModule.getGlobalVariable(Name); if (!GV) { - // Emit a placeholder symbol. + // Emit a placeholder symbol. GV = new llvm::GlobalVariable(TheModule, ProtocolTy, false, llvm::GlobalValue::ExternalLinkage, nullptr, Name); GV->setAlignment(CGM.getPointerAlign().getQuantity()); @@ -1281,7 +1281,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { return Protocol; EmittedProtocol = true; - + // Use the protocol definition, if there is one. if (const ObjCProtocolDecl *Def = PD->getDefinition()) PD = Def; @@ -1680,7 +1680,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { OffsetVar = new llvm::GlobalVariable(TheModule, IntTy, false, llvm::GlobalValue::ExternalLinkage, OffsetValue, OffsetName); - auto ivarVisibility = + auto ivarVisibility = (IVD->getAccessControl() == ObjCIvarDecl::Private || IVD->getAccessControl() == ObjCIvarDecl::Package || classDecl->getVisibility() == HiddenVisibility) ? @@ -1700,14 +1700,14 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { // Bits 0-1 are ownership. // Bit 2 indicates an extended type encoding // Bits 3-8 contain log2(aligment) - ivarBuilder.addInt(Int32Ty, + ivarBuilder.addInt(Int32Ty, (align << 3) | (1<<2) | FlagsForOwnership(ivarTy.getQualifiers().getObjCLifetime())); ivarBuilder.finishAndAddTo(ivarArrayBuilder); } ivarArrayBuilder.finishAndAddTo(ivarListBuilder); auto ivarList = ivarListBuilder.finishAndCreateGlobal(".objc_ivar_list", - CGM.getPointerAlign(), /*constant*/ false, + CGM.getPointerAlign(), /*constant*/ false, llvm::GlobalValue::PrivateLinkage); classFields.add(ivarList); } @@ -2448,7 +2448,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, // returns. With GCC, this generates a random return value (whatever happens // to be on the stack / in those registers at the time) on most platforms, // and generates an illegal instruction trap on SPARC. With LLVM it corrupts - // the stack. + // the stack. bool isPointerSizedReturn = (ResultType->isAnyPointerType() || ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType()); @@ -2461,7 +2461,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, messageBB = CGF.createBasicBlock("msgSend"); continueBB = CGF.createBasicBlock("continue"); - llvm::Value *isNil = Builder.CreateICmpEQ(Receiver, + llvm::Value *isNil = Builder.CreateICmpEQ(Receiver, llvm::Constant::getNullValue(Receiver->getType())); Builder.CreateCondBr(isNil, continueBB, messageBB); CGF.EmitBlock(messageBB); @@ -2495,7 +2495,7 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, // If we have non-legacy dispatch specified, we try using the objc_msgSend() // functions. These are not supported on all platforms (or all runtimes on a - // given platform), so we + // given platform), so we switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { case CodeGenOptions::Legacy: imp = LookupIMP(CGF, Receiver, cmd, node, MSI); @@ -2720,7 +2720,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure( // Fill in the structure - // isa + // isa Elements.addBitCast(MetaClass, PtrToInt8Ty); // super_class Elements.add(SuperClass); @@ -2869,7 +2869,7 @@ CGObjCGNU::GenerateEmptyProtocol(StringRef ProtocolName) { void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) { std::string ProtocolName = PD->getNameAsString(); - + // Use the protocol definition, if there is one. if (const ObjCProtocolDecl *Def = PD->getDefinition()) PD = Def; @@ -2977,7 +2977,7 @@ void CGObjCGNU::GenerateProtocolHolderCategory() { /// stored in a 64-bit value with the low bit set to 1 and the remaining 63 /// bits set to their values, LSB first, while larger ones are stored in a /// structure of this / form: -/// +/// /// struct { int32_t length; int32_t values[length]; }; /// /// The values in the array are stored in host-endian format, with the least @@ -3200,7 +3200,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { } // Get the size of instances. - int instanceSize = + int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize().getQuantity(); // Collect information about instance variables. @@ -3291,7 +3291,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { // Collect the same information about synthesized properties, which don't // show up in the instance method lists. for (auto *propertyImpl : OID->property_impls()) - if (propertyImpl->getPropertyImplementation() == + if (propertyImpl->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { ObjCPropertyDecl *property = propertyImpl->getPropertyDecl(); auto addPropertyMethod = [&](const ObjCMethodDecl *accessor) { @@ -3718,7 +3718,7 @@ void CGObjCGNU::EmitTryStmt(CodeGenFunction &CGF, // interoperate very well with foreign exceptions. // // In Objective-C++ mode, we actually emit something equivalent to the C++ - // exception handler. + // exception handler. EmitTryCatchStmt(CGF, S, EnterCatchFn, ExitCatchFn, ExceptionReThrowFn); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0c766575dc21..2b54e7bd67af 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -57,7 +57,7 @@ private: // should always bitcast before calling them. /// id objc_msgSend (id, SEL, ...) - /// + /// /// The default messenger, used for sends whose ABI is unchanged from /// the all-integer/pointer case. llvm::Constant *getMessageSendFn() const { @@ -184,12 +184,12 @@ public: /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) llvm::PointerType *SelectorPtrTy; - + private: /// ProtocolPtrTy - LLVM type for external protocol handles /// (typeof(Protocol)) llvm::Type *ExternalProtocolPtrTy; - + public: llvm::Type *getExternalProtocolPtrTy() { if (!ExternalProtocolPtrTy) { @@ -200,10 +200,10 @@ public: llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); } - + return ExternalProtocolPtrTy; } - + // SuperCTy - clang type for struct objc_super. QualType SuperCTy; // SuperPtrCTy - clang type for struct objc_super *. @@ -231,7 +231,7 @@ public: llvm::Type *CacheTy; /// CachePtrTy - LLVM type for struct objc_cache *. llvm::PointerType *CachePtrTy; - + llvm::Constant *getGetPropertyFn() { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); @@ -269,15 +269,15 @@ public: llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); - // void objc_setProperty_atomic(id self, SEL _cmd, + // void objc_setProperty_atomic(id self, SEL _cmd, // id newValue, ptrdiff_t offset); - // void objc_setProperty_nonatomic(id self, SEL _cmd, + // void objc_setProperty_nonatomic(id self, SEL _cmd, // id newValue, ptrdiff_t offset); - // void objc_setProperty_atomic_copy(id self, SEL _cmd, + // void objc_setProperty_atomic_copy(id self, SEL _cmd, // id newValue, ptrdiff_t offset); - // void objc_setProperty_nonatomic_copy(id self, SEL _cmd, + // void objc_setProperty_nonatomic_copy(id self, SEL _cmd, // id newValue, ptrdiff_t offset); - + SmallVector<CanQualType,4> Params; CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); @@ -297,10 +297,10 @@ public: name = "objc_setProperty_nonatomic_copy"; else name = "objc_setProperty_nonatomic"; - + return CGM.CreateRuntimeFunction(FTy, name); } - + llvm::Constant *getCopyStructFn() { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); @@ -316,10 +316,10 @@ public: Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); } - + /// This routine declares and returns address of: /// void objc_copyCppObjectAtomic( - /// void *dest, const void *src, + /// void *dest, const void *src, /// void (*copyHelper) (void *dest, const void *source)); llvm::Constant *getCppAtomicObjectFunction() { CodeGen::CodeGenTypes &Types = CGM.getTypes(); @@ -334,7 +334,7 @@ public: Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params)); return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic"); } - + llvm::Constant *getEnumerationMutationFn() { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); @@ -396,7 +396,7 @@ public: llvm::FunctionType::get(ObjectPtrTy, args, false); return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal"); } - + /// GcAssignIvarFn -- LLVM objc_assign_ivar function. llvm::Constant *getGcAssignIvarFn() { // id objc_assign_ivar(id, id *, ptrdiff_t) @@ -439,7 +439,7 @@ public: llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false); return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow"); } - + /// SyncEnterFn - LLVM object_sync_enter function. llvm::Constant *getSyncEnterFn() { // int objc_sync_enter (id) @@ -550,7 +550,7 @@ public: /// ExceptionDataTy - LLVM type for struct _objc_exception_data. llvm::StructType *ExceptionDataTy; - + /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. llvm::Constant *getExceptionTryEnterFn() { llvm::Type *params[] = { ExceptionDataTy->getPointerTo() }; @@ -727,7 +727,7 @@ public: llvm::StructType *EHTypeTy; llvm::Type *EHTypePtrTy; - + ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); }; @@ -760,33 +760,33 @@ public: /// to '\0'. /// I != 0: Currently unused. BLOCK_LAYOUT_OPERATOR = 0, - + /// The next I+1 bytes do not contain a value of object pointer type. /// Note that this can leave the stream unaligned, meaning that /// subsequent word-size instructions do not begin at a multiple of /// the pointer size. BLOCK_LAYOUT_NON_OBJECT_BYTES = 1, - + /// The next I+1 words do not contain a value of object pointer type. /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for /// when the required skip quantity is a multiple of the pointer size. BLOCK_LAYOUT_NON_OBJECT_WORDS = 2, - + /// The next I+1 words are __strong pointers to Objective-C /// objects or blocks. BLOCK_LAYOUT_STRONG = 3, - + /// The next I+1 words are pointers to __block variables. BLOCK_LAYOUT_BYREF = 4, - + /// The next I+1 words are __weak pointers to Objective-C /// objects or blocks. BLOCK_LAYOUT_WEAK = 5, - + /// The next I+1 words are __unsafe_unretained pointers to /// Objective-C objects or blocks. BLOCK_LAYOUT_UNRETAINED = 6 - + /// The next I+1 words are block or object pointers with some /// as-yet-unspecified ownership semantics. If we add more /// flavors of ownership semantics, values will be taken from @@ -795,11 +795,11 @@ public: /// This is included so that older tools can at least continue /// processing the layout past such things. //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10, - + /// All other opcodes are reserved. Halt interpretation and /// treat everything else as opaque. }; - + class RUN_SKIP { public: enum BLOCK_LAYOUT_OPCODE opcode; @@ -809,13 +809,13 @@ public: CharUnits BytePos = CharUnits::Zero(), CharUnits Size = CharUnits::Zero()) : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {} - + // Allow sorting based on byte pos. bool operator<(const RUN_SKIP &b) const { return block_var_bytepos < b.block_var_bytepos; } }; - + protected: llvm::LLVMContext &VMContext; // FIXME! May not be needing this after all. @@ -871,7 +871,7 @@ protected: /// DefinedClasses - List of defined classes. SmallVector<llvm::GlobalValue*, 16> DefinedClasses; - + /// ImplementedClasses - List of @implemented classes. SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses; @@ -952,28 +952,28 @@ protected: bool hasMRCWeakIvars) { return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars); } - + Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout); - + void UpdateRunSkipBlockVars(bool IsByref, Qualifiers::ObjCLifetime LifeTime, CharUnits FieldOffset, CharUnits FieldSize); - + void BuildRCBlockVarRecordLayout(const RecordType *RT, CharUnits BytePos, bool &HasUnion, bool ByrefLayout=false); - + void BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordDecl *RD, ArrayRef<const FieldDecl*> RecFields, CharUnits BytePos, bool &HasUnion, bool ByrefLayout); - + uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout); - + llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout); - + /// GetIvarLayoutName - Returns a unique constant for the given /// ivar layout bitmap. llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, @@ -987,9 +987,9 @@ protected: const ObjCCommonTypesHelper &ObjCTypes, bool IsClassProperty); - /// EmitProtocolMethodTypes - Generate the array of extended method type + /// EmitProtocolMethodTypes - Generate the array of extended method type /// strings. The return value has type Int8PtrPtrTy. - llvm::Constant *EmitProtocolMethodTypes(Twine Name, + llvm::Constant *EmitProtocolMethodTypes(Twine Name, ArrayRef<llvm::Constant*> MethodTypes, const ObjCCommonTypesHelper &ObjCTypes); @@ -1205,7 +1205,7 @@ private: /// for the given class. llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID); - + llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II); @@ -1382,7 +1382,7 @@ private: /// DefinedMetaClasses - List of defined meta-classes. std::vector<llvm::GlobalValue*> DefinedMetaClasses; - + /// isVTableDispatchedSelector - Returns true if SEL is a /// vtable-based selector. bool isVTableDispatchedSelector(Selector Sel); @@ -1453,7 +1453,7 @@ private: bool IsSuper, const CallArgList &CallArgs, const ObjCMethodDecl *Method); - + /// GetClassGlobal - Return the global variable for the Objective-C /// class of the given name. llvm::Constant *GetClassGlobal(StringRef Name, @@ -1467,7 +1467,7 @@ private: /// for the given class reference. llvm::Value *EmitClassRef(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID); - + llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II, const ObjCInterfaceDecl *ID); @@ -1700,7 +1700,7 @@ struct NullReturnState { // Okay, start emitting the null-receiver block. CGF.EmitBlock(NullBB); - + // Release any consumed arguments we've got. if (Method) { CallArgList::const_iterator I = CallArgs.begin(); @@ -1709,7 +1709,7 @@ struct NullReturnState { const ParmVarDecl *ParamDecl = (*i); if (ParamDecl->hasAttr<NSConsumedAttr>()) { RValue RV = I->getRValue(CGF); - assert(RV.isScalar() && + assert(RV.isScalar() && "NullReturnState::complete - arg not on object"); CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime); } @@ -1839,7 +1839,7 @@ llvm::Constant *CGObjCMac::GetEHType(QualType T) { } if (T->isObjCObjectPointerType()) return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true); - + llvm_unreachable("asking for catch type for ObjC type in fragile runtime"); } @@ -1898,8 +1898,8 @@ llvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() { return cast<llvm::Constant>(V); auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass; - std::string str = - StringClass.empty() ? "OBJC_CLASS_$_NSConstantString" + std::string str = + StringClass.empty() ? "OBJC_CLASS_$_NSConstantString" : "OBJC_CLASS_$_" + StringClass; auto GV = GetClassGlobal(str, NotForDefinition); @@ -2162,7 +2162,7 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, if (RequiresNullCheck) { nullReturn.init(CGF, Arg0); } - + llvm::Instruction *CallSite; Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType); CGCallee Callee = CGCallee::forDirect(Fn); @@ -2202,17 +2202,17 @@ static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT, } llvm_unreachable("bad objc ownership"); } - + // Treat unqualified retainable pointers as strong. if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) return Qualifiers::Strong; - + // Walk into C pointer types, but only in GC. if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) { if (const PointerType *PT = FQT->getAs<PointerType>()) return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true); } - + return Qualifiers::GCNone; } @@ -2258,7 +2258,7 @@ namespace { void visitRecord(const RecordType *RT, CharUnits offset); template <class Iterator, class GetOffsetFn> - void visitAggregate(Iterator begin, Iterator end, + void visitAggregate(Iterator begin, Iterator end, CharUnits aggrOffset, const GetOffsetFn &getOffset); @@ -2287,7 +2287,7 @@ namespace { llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, const CGBlockInfo &blockInfo) { - + llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy); if (CGM.getLangOpts().getGC() == LangOptions::NonGC) return nullPtr; @@ -2306,7 +2306,7 @@ llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM, printf("\n block variable layout for block: "); builder.dump(buffer); } - + return C; } @@ -2351,7 +2351,7 @@ void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) { visitRecord(record, fieldOffset); continue; } - + Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type); if (GCAttr == Qualifiers::Strong) { @@ -2374,11 +2374,11 @@ Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT, // If it doesn't, and this is ARC, it has no ownership. if (CGM.getLangOpts().ObjCAutoRefCount) return Qualifiers::OCL_None; - + // In MRC, retainable pointers are owned by non-__block variables. if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong; - + return Qualifiers::OCL_None; } @@ -2416,11 +2416,11 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr; CharUnits MaxFieldOffset = CharUnits::Zero(); CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero(); - + if (RecFields.empty()) return; unsigned ByteSizeInBits = CGM.getTarget().getCharWidth(); - + for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { const FieldDecl *Field = RecFields[i]; // Note that 'i' here is actually the field index inside RD of Field, @@ -2428,7 +2428,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); CharUnits FieldOffset = CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i)); - + // Skip over unnamed or bitfields if (!Field->getIdentifier() || Field->isBitField()) { LastFieldBitfieldOrUnnamed = Field; @@ -2441,12 +2441,12 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, if (FQT->isRecordType() || FQT->isUnionType()) { if (FQT->isUnionType()) HasUnion = true; - + BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(), BytePos + FieldOffset, HasUnion); continue; } - + if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { const ConstantArrayType *CArray = dyn_cast_or_null<ConstantArrayType>(Array); @@ -2464,7 +2464,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, const RecordType *RT = FQT->getAs<RecordType>(); BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset, HasUnion); - + // Replicate layout information for each array element. Note that // one element is already done. uint64_t ElIx = 1; @@ -2494,7 +2494,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, FieldSize); } } - + if (LastFieldBitfieldOrUnnamed) { if (LastFieldBitfieldOrUnnamed->isBitField()) { // Last field was a bitfield. Must update the info. @@ -2521,7 +2521,7 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, FieldSize); } } - + if (MaxField) UpdateRunSkipBlockVars(false, getBlockCaptureLifetime(MaxField->getType(), ByrefLayout), @@ -2538,7 +2538,7 @@ void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT, llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); const llvm::StructLayout *RecLayout = CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty)); - + BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout); } @@ -2580,7 +2580,7 @@ uint64_t CGObjCCommonMac::InlineLayoutInstruction( else return 0; break; - + case 2: inst = Layout[0]; opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4); @@ -2607,7 +2607,7 @@ uint64_t CGObjCCommonMac::InlineLayoutInstruction( else return 0; break; - + case 1: inst = Layout[0]; opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4); @@ -2620,20 +2620,20 @@ uint64_t CGObjCCommonMac::InlineLayoutInstruction( else return 0; break; - + default: return 0; } - + // Cannot inline when any of the word counts is 15. Because this is one less // than the actual work count (so 15 means 16 actual word counts), // and we can only display 0 thru 15 word counts. if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16) return 0; - + unsigned count = (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0); - + if (size == count) { if (strong_word_count) Result = strong_word_count; @@ -2655,12 +2655,12 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0); unsigned ByteSizeInBits = CGM.getTarget().getCharWidth(); unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits; - + // Sort on byte position; captures might not be allocated in order, // and unions can do funny things. llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end()); SmallVector<unsigned char, 16> Layout; - + unsigned size = RunSkipBlockVars.size(); for (unsigned i = 0; i < size; i++) { enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode; @@ -2689,7 +2689,7 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { size_in_bytes -= residue_in_bytes; opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS; } - + unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes; while (size_in_words >= 16) { // Note that value in imm. is one less that the actual @@ -2710,7 +2710,7 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { Layout.push_back(inst); } } - + while (!Layout.empty()) { unsigned char inst = Layout.back(); enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4); @@ -2719,7 +2719,7 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { else break; } - + uint64_t Result = InlineLayoutInstruction(Layout); if (Result != 0) { // Block variable layout instruction has been inlined. @@ -2739,13 +2739,13 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { } return llvm::ConstantInt::get(CGM.IntPtrTy, Result); } - + unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0; Layout.push_back(inst); std::string BitMap; for (unsigned i = 0, e = Layout.size(); i != e; i++) BitMap += Layout[i]; - + if (CGM.getLangOpts().ObjCGCBitmapPrint) { if (ComputeByrefLayout) printf("\n Byref variable layout: "); @@ -2798,20 +2798,20 @@ llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) { llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, const CGBlockInfo &blockInfo) { assert(CGM.getLangOpts().getGC() == LangOptions::NonGC); - + RunSkipBlockVars.clear(); bool hasUnion = false; - + unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0); unsigned ByteSizeInBits = CGM.getTarget().getCharWidth(); unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits; - + const BlockDecl *blockDecl = blockInfo.getBlockDecl(); - + // Calculate the basic layout of the block structure. const llvm::StructLayout *layout = CGM.getDataLayout().getStructLayout(blockInfo.StructureType); - + // Ignore the optional 'this' capture: C++ objects are not assumed // to be GC'ed. if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero()) @@ -2822,15 +2822,15 @@ llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM, for (const auto &CI : blockDecl->captures()) { const VarDecl *variable = CI.getVariable(); QualType type = variable->getType(); - + const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); - + // Ignore constant captures. if (capture.isConstant()) continue; - + CharUnits fieldOffset = CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex())); - + assert(!type->isArrayType() && "array variable should not be caught"); if (!CI.isByRef()) if (const RecordType *record = type->getAs<RecordType>()) { @@ -2891,7 +2891,7 @@ void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { if (DefinedProtocols.count(PD->getIdentifier())) return GetOrEmitProtocol(PD); - + return GetOrEmitProtocolRef(PD); } @@ -3094,12 +3094,12 @@ CGObjCMac::EmitProtocolList(Twine name, return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); } -static void +static void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet, SmallVectorImpl<const ObjCPropertyDecl *> &Properties, const ObjCProtocolDecl *Proto, bool IsClassProperty) { - for (const auto *P : Proto->protocols()) + for (const auto *P : Proto->protocols()) PushProtocolProperties(PropertySet, Properties, P, IsClassProperty); for (const auto *PD : Proto->properties()) { @@ -3679,7 +3679,7 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, auto countSlot = ivarList.addPlaceholder(); auto ivars = ivarList.beginArray(ObjCTypes.IvarTy); - for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); + for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD; IVD = IVD->getNextIvar()) { // Ignore unnamed bit-fields. if (!IVD->getDeclName()) @@ -3964,7 +3964,7 @@ llvm::Constant *CGObjCMac::GetPropertySetFunction() { return ObjCTypes.getSetPropertyFn(); } -llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic, +llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic, bool copy) { return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy); } @@ -4959,9 +4959,9 @@ llvm::Constant *CGObjCMac::EmitModuleSymbols() { llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, IdentifierInfo *II) { LazySymbols.insert(II); - + llvm::GlobalVariable *&Entry = ClassReferences[II]; - + if (!Entry) { llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(GetClassName(II->getName()), @@ -4971,7 +4971,7 @@ llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF, "__OBJC,__cls_refs,literal_pointers,no_dead_strip", CGM.getPointerAlign(), true); } - + return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign()); } @@ -5056,7 +5056,7 @@ void IvarLayoutBuilder::visitRecord(const RecordType *RT, } template <class Iterator, class GetOffsetFn> -void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end, +void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end, CharUnits aggregateOffset, const GetOffsetFn &getOffset) { for (; begin != end; ++begin) { @@ -5317,7 +5317,7 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD, // MRC weak layout strings follow the ARC style. CharUnits baseOffset; if (CGM.getLangOpts().getGC() == LangOptions::NonGC) { - for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); + for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin(); IVD; IVD = IVD->getNextIvar()) ivars.push_back(IVD); @@ -5353,7 +5353,7 @@ CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD, llvm::SmallVector<unsigned char, 4> buffer; llvm::Constant *C = builder.buildBitmap(*this, buffer); - + if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) { printf("\n%s ivar layout for class '%s': ", ForStrongLayout ? "strong" : "weak", @@ -5903,7 +5903,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); - + // struct objc_typeinfo { // const void** vtable; // objc_ehtype_vtable + 2 @@ -6033,7 +6033,7 @@ bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) { if (CGM.getLangOpts().getGC() != LangOptions::NonGC) { VTableDispatchMethods.insert(GetNullarySelector("hash")); VTableDispatchMethods.insert(GetUnarySelector("addObject")); - + // "countByEnumeratingWithState:objects:count" IdentifierInfo *KeyIdents[] = { &CGM.getContext().Idents.get("countByEnumeratingWithState"), @@ -6418,12 +6418,12 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF, void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); const char *Prefix = "\01l_OBJC_$_CATEGORY_"; - + llvm::SmallString<64> ExtCatName(Prefix); ExtCatName += Interface->getObjCRuntimeNameAsString(); ExtCatName += "_$_"; ExtCatName += OCD->getNameAsString(); - + ConstantInitBuilder builder(CGM); auto values = builder.beginStruct(ObjCTypes.CategorynfABITy); values.add(GetClassName(OCD->getIdentifier()->getName())); @@ -6684,7 +6684,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( // FIXME. Consolidate this with similar code in GenerateClass. - for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); + for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); IVD; IVD = IVD->getNextIvar()) { // Ignore unnamed bit-fields. if (!IVD->getDeclName()) @@ -6785,7 +6785,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( // Use the protocol definition, if there is one. if (const ObjCProtocolDecl *Def = PD->getDefinition()) PD = Def; - + auto methodLists = ProtocolMethodLists::get(PD); ConstantInitBuilder builder(CGM); @@ -6824,7 +6824,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( values.add(EmitPropertyList( "\01l_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(), nullptr, PD, ObjCTypes, true)); - + if (Entry) { // Already created, fix the linkage and update the initializer. Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); @@ -7058,7 +7058,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); messageRef->setSection(GetSectionName("__objc_msgrefs", "coalesced")); } - + bool requiresnullCheck = false; if (CGM.getLangOpts().ObjCAutoRefCount && method) for (const auto *ParamDecl : method->parameters()) { @@ -7069,7 +7069,7 @@ CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, break; } } - + Address mref = Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy), CGF.getPointerAlign()); @@ -7153,7 +7153,7 @@ CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, const ObjCInterfaceDecl *ID) { CharUnits Align = CGF.getPointerAlign(); llvm::GlobalVariable *&Entry = ClassReferences[II]; - + if (!Entry) { llvm::Constant *ClassGV; if (ID) { @@ -7243,7 +7243,7 @@ llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF, assert(!isa<llvm::GlobalVariable>(ClassGV) || cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage()); } - + return EmitClassRef(CGF, ID); } @@ -7304,7 +7304,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, Address Addr = EmitSelectorAddr(CGF, Sel); llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr); - LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), + LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), llvm::MDNode::get(VMContext, None)); return LI; } diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp index 2f886fd82caa..a43885c0f9a2 100644 --- a/lib/CodeGen/CGObjCRuntime.cpp +++ b/lib/CodeGen/CGObjCRuntime.cpp @@ -181,7 +181,7 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, for (unsigned I = 0, E = Handlers.size(); I != E; ++I) Catch->setHandler(I, Handlers[I].TypeInfo, Handlers[I].Block); } - + // Emit the try body. CGF.EmitStmt(S.getTryBody()); @@ -232,7 +232,7 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, cleanups.ForceCleanup(); CGF.EmitBranchThroughCleanup(Cont); - } + } // Go back to the try-statement fallthrough. CGF.Builder.restoreIP(SavedIP); diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index a14b44abf413..ce082a61eb5e 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -143,7 +143,7 @@ public: /// Generate a constant string object. virtual ConstantAddress GenerateConstantString(const StringLiteral *) = 0; - + /// Generate a category. A category contains a list of methods (and /// accompanying metadata) and a list of protocols. virtual void GenerateCategory(const ObjCCategoryImplDecl *OCD) = 0; @@ -211,7 +211,7 @@ public: virtual llvm::Constant *GetPropertySetFunction() = 0; /// Return the runtime function for optimized setting properties. - virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, + virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, bool copy) = 0; // API for atomic copying of qualified aggregates in getter. @@ -224,17 +224,17 @@ public: /// API for atomic copying of qualified aggregates with non-trivial copy /// assignment (c++) in getter. virtual llvm::Constant *GetCppAtomicObjectGetFunction() = 0; - + /// GetClass - Return a reference to the class for the given /// interface decl. virtual llvm::Value *GetClass(CodeGenFunction &CGF, const ObjCInterfaceDecl *OID) = 0; - - + + virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) { llvm_unreachable("autoreleasepool unsupported in this ABI"); } - + /// EnumerationMutationFunction - Return the function that's called by the /// compiler when a mutation is detected during foreach iteration. virtual llvm::Constant *EnumerationMutationFunction() = 0; diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 3730b9af12fa..fa850155df4f 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -3750,11 +3750,13 @@ CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() { StringRef T = Device.getTriple(); std::string BeginName = getName({"omp_offloading", "img_start", ""}); auto *ImgBegin = new llvm::GlobalVariable( - M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, + M, CGM.Int8Ty, /*isConstant=*/true, + llvm::GlobalValue::ExternalWeakLinkage, /*Initializer=*/nullptr, Twine(BeginName).concat(T)); std::string EndName = getName({"omp_offloading", "img_end", ""}); auto *ImgEnd = new llvm::GlobalVariable( - M, CGM.Int8Ty, /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, + M, CGM.Int8Ty, /*isConstant=*/true, + llvm::GlobalValue::ExternalWeakLinkage, /*Initializer=*/nullptr, Twine(EndName).concat(T)); llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin, @@ -8109,6 +8111,19 @@ void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD, VarName = CGM.getMangledName(VD); VarSize = CGM.getContext().getTypeSizeInChars(VD->getType()); Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false); + // Temp solution to prevent optimizations of the internal variables. + if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) { + std::string RefName = getName({VarName, "ref"}); + if (!CGM.GetGlobalValue(RefName)) { + llvm::Constant *AddrRef = + getOrCreateInternalVariable(Addr->getType(), RefName); + auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef); + GVAddrRef->setConstant(/*Val=*/true); + GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage); + GVAddrRef->setInitializer(Addr); + CGM.addCompilerUsedGlobal(GVAddrRef); + } + } break; case OMPDeclareTargetDeclAttr::MT_Link: Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink; diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 4ee6c8e71457..58aaae692552 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -166,7 +166,7 @@ struct CGRecordLowering { return Layout.getFieldOffset(FD->getFieldIndex()); } // Layout routines. - void setBitFieldInfo(const FieldDecl *FD, CharUnits StartOffset, + void setBitFieldInfo(const FieldDecl *FD, CharUnits StartOffset, llvm::Type *StorageType); /// Lowers an ASTRecordLayout to a llvm type. void lower(bool NonVirtualBaseType); @@ -246,7 +246,7 @@ void CGRecordLowering::lower(bool NVBaseType) { // 1) Store all members (fields and bases) in a list and sort them by offset. // 2) Add a 1-byte capstone member at the Size of the structure. // 3) Clip bitfield storages members if their tail padding is or might be - // used by another field or base. The clipping process uses the capstone + // used by another field or base. The clipping process uses the capstone // by treating it as another object that occurs after the record. // 4) Determine if the llvm-struct requires packing. It's important that this // phase occur after clipping, because clipping changes the llvm type. @@ -313,9 +313,8 @@ void CGRecordLowering::lowerUnion() { if (!SeenNamedMember) { SeenNamedMember = Field->getIdentifier(); if (!SeenNamedMember) - if (const auto *FieldRD = - dyn_cast_or_null<RecordDecl>(Field->getType()->getAsTagDecl())) - SeenNamedMember = FieldRD->findFirstNamedDataMember(); + if (const auto *FieldRD = Field->getType()->getAsRecordDecl()) + SeenNamedMember = FieldRD->findFirstNamedDataMember(); if (SeenNamedMember && !isZeroInitializable(Field)) { IsZeroInitializable = IsZeroInitializableAsBase = false; StorageType = FieldType; @@ -437,7 +436,7 @@ CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field, StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, - StartBitOffset); + StartBitOffset); } ++Field; continue; @@ -687,7 +686,7 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, uint64_t Offset, uint64_t Size, uint64_t StorageSize, CharUnits StorageOffset) { - // This function is vestigial from CGRecordLayoutBuilder days but is still + // This function is vestigial from CGRecordLayoutBuilder days but is still // used in GCObjCRuntime.cpp. That usage has a "fixme" attached to it that // when addressed will allow for the removal of this function. llvm::Type *Ty = Types.ConvertTypeForMem(FD->getType()); @@ -782,14 +781,14 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, if (BaseTy) { CharUnits NonVirtualSize = Layout.getNonVirtualSize(); - uint64_t AlignedNonVirtualTypeSizeInBits = + uint64_t AlignedNonVirtualTypeSizeInBits = getContext().toBits(NonVirtualSize); - assert(AlignedNonVirtualTypeSizeInBits == + assert(AlignedNonVirtualTypeSizeInBits == getDataLayout().getTypeAllocSizeInBits(BaseTy) && "Type size mismatch!"); } - + // Verify that the LLVM and AST field offsets agree. llvm::StructType *ST = RL->getLLVMType(); const llvm::StructLayout *SL = getDataLayout().getStructLayout(ST); @@ -807,7 +806,7 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, "Invalid field offset!"); continue; } - + // Ignore unnamed bit-fields. if (!FD->getDeclName()) continue; @@ -854,7 +853,7 @@ void CGRecordLayout::print(raw_ostream &OS) const { OS << "<CGRecordLayout\n"; OS << " LLVMType:" << *CompleteObjectType << "\n"; if (BaseSubobjectType) - OS << " NonVirtualBaseLLVMType:" << *BaseSubobjectType << "\n"; + OS << " NonVirtualBaseLLVMType:" << *BaseSubobjectType << "\n"; OS << " IsZeroInitializable:" << IsZeroInitializable << "\n"; OS << " BitFields:[\n"; diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 41c8c943f54d..b0a3a0bffa2e 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -30,8 +30,8 @@ GetAddrOfVTTVTable(CodeGenVTables &CGVT, CodeGenModule &CGM, // This is a regular vtable. return CGM.getCXXABI().getAddrOfVTable(MostDerivedClass, CharUnits()); } - - return CGVT.GenerateConstructionVTable(MostDerivedClass, + + return CGVT.GenerateConstructionVTable(MostDerivedClass, VTable.getBaseSubobject(), VTable.isVirtual(), Linkage, @@ -45,7 +45,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT, VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/true); llvm::Type *Int8PtrTy = CGM.Int8PtrTy, *Int32Ty = CGM.Int32Ty; - llvm::ArrayType *ArrayType = + llvm::ArrayType *ArrayType = llvm::ArrayType::get(Int8PtrTy, Builder.getVTTComponents().size()); SmallVector<llvm::GlobalVariable *, 8> VTables; @@ -117,42 +117,42 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) { VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false); - llvm::ArrayType *ArrayType = + llvm::ArrayType *ArrayType = llvm::ArrayType::get(CGM.Int8PtrTy, Builder.getVTTComponents().size()); llvm::GlobalVariable *GV = - CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, + CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, llvm::GlobalValue::ExternalLinkage); GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); return GV; } -uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, +uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base) { BaseSubobjectPairTy ClassSubobjectPair(RD, Base); SubVTTIndiciesMapTy::iterator I = SubVTTIndicies.find(ClassSubobjectPair); if (I != SubVTTIndicies.end()) return I->second; - + VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false); for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = - Builder.getSubVTTIndicies().begin(), + Builder.getSubVTTIndicies().begin(), E = Builder.getSubVTTIndicies().end(); I != E; ++I) { // Insert all indices. BaseSubobjectPairTy ClassSubobjectPair(RD, I->first); - + SubVTTIndicies.insert(std::make_pair(ClassSubobjectPair, I->second)); } - + I = SubVTTIndicies.find(ClassSubobjectPair); assert(I != SubVTTIndicies.end() && "Did not find index!"); - + return I->second; } -uint64_t +uint64_t CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, BaseSubobject Base) { SecondaryVirtualPointerIndicesMapTy::iterator I = @@ -164,17 +164,17 @@ CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, VTTBuilder Builder(CGM.getContext(), RD, /*GenerateDefinition=*/false); // Insert all secondary vpointer indices. - for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = + for (llvm::DenseMap<BaseSubobject, uint64_t>::const_iterator I = Builder.getSecondaryVirtualPointerIndices().begin(), E = Builder.getSecondaryVirtualPointerIndices().end(); I != E; ++I) { std::pair<const CXXRecordDecl *, BaseSubobject> Pair = std::make_pair(RD, I->first); - + SecondaryVirtualPointerIndices.insert(std::make_pair(Pair, I->second)); } I = SecondaryVirtualPointerIndices.find(std::make_pair(RD, Base)); assert(I != SecondaryVirtualPointerIndices.end() && "Did not find index!"); - + return I->second; } diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index 5a2ec65f7763..cc334637a831 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -110,7 +110,7 @@ static RValue PerformReturnAdjustment(CodeGenFunction &CGF, return RValue::get(ReturnValue); } -/// This function clones a function's DISubprogram node and enters it into +/// This function clones a function's DISubprogram node and enters it into /// a value map with the intent that the map can be utilized by the cloner /// to short-circuit Metadata node mapping. /// Furthermore, the function resolves any DILocalVariable nodes referenced diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index a11474a15ea4..6377659e4cb3 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -40,7 +40,7 @@ class CodeGenVTables { typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy; - + /// SubVTTIndicies - Contains indices into the various sub-VTTs. SubVTTIndiciesMapTy SubVTTIndicies; @@ -87,21 +87,21 @@ public: /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the /// given record decl. uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base); - + /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the /// virtual pointer for the given subobject is located. uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, BaseSubobject Base); - /// GenerateConstructionVTable - Generate a construction vtable for the given + /// GenerateConstructionVTable - Generate a construction vtable for the given /// base subobject. llvm::GlobalVariable * - GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, - bool BaseIsVirtual, + GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, + bool BaseIsVirtual, llvm::GlobalVariable::LinkageTypes Linkage, VTableAddressPointsMapTy& AddressPoints); - + /// GetAddrOfVTT - Get the address of the VTT for the given record decl. llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD); @@ -112,7 +112,7 @@ public: /// EmitThunks - Emit the associated thunks for the given global decl. void EmitThunks(GlobalDecl GD); - + /// GenerateClassData - Generate all the class data required to be /// generated upon definition of a KeyFunction. This includes the /// vtable, the RTTI data structure (if RTTI is enabled) and the VTT diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 418bda1f41bb..0dcbea423ad7 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -197,7 +197,7 @@ class LValue { // objective-c's ivar bool Ivar:1; - + // objective-c's ivar is an array bool ObjIsArray:1; @@ -207,7 +207,7 @@ class LValue { // Lvalue is a global reference of an objective-c object bool GlobalObjCRef : 1; - + // Lvalue is a thread local reference bool ThreadLocalRef : 1; @@ -301,7 +301,7 @@ public: bool isVolatile() const { return Quals.hasVolatile(); } - + Expr *getBaseIvarExp() const { return BaseIvarExp; } void setBaseIvarExp(Expr *V) { BaseIvarExp = V; } @@ -452,7 +452,7 @@ class AggValueSlot { /// slot might require calling an appropriate Objective-C GC /// barrier. The exact interaction here is unnecessarily mysterious. bool ObjCGCFlag : 1; - + /// ZeroedFlag - This is set to true if the memory in the slot is /// known to be zero before the assignment into it. This means that /// zero fields don't need to be set. @@ -472,19 +472,27 @@ class AggValueSlot { /// evaluating an expression which constructs such an object. bool AliasedFlag : 1; - /// This is set to true if the tail padding of this slot might overlap + /// This is set to true if the tail padding of this slot might overlap /// another object that may have already been initialized (and whose /// value must be preserved by this initialization). If so, we may only /// store up to the dsize of the type. Otherwise we can widen stores to /// the size of the type. bool OverlapFlag : 1; + /// If is set to true, sanitizer checks are already generated for this address + /// or not required. For instance, if this address represents an object + /// created in 'new' expression, sanitizer checks for memory is made as a part + /// of 'operator new' emission and object constructor should not generate + /// them. + bool SanitizerCheckedFlag : 1; + public: enum IsAliased_t { IsNotAliased, IsAliased }; enum IsDestructed_t { IsNotDestructed, IsDestructed }; enum IsZeroed_t { IsNotZeroed, IsZeroed }; enum Overlap_t { DoesNotOverlap, MayOverlap }; enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; + enum IsSanitizerChecked_t { IsNotSanitizerChecked, IsSanitizerChecked }; /// ignored - Returns an aggregate value slot indicating that the /// aggregate value is being ignored. @@ -509,7 +517,8 @@ public: NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, - IsZeroed_t isZeroed = IsNotZeroed) { + IsZeroed_t isZeroed = IsNotZeroed, + IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) { AggValueSlot AV; if (addr.isValid()) { AV.Addr = addr.getPointer(); @@ -524,6 +533,7 @@ public: AV.ZeroedFlag = isZeroed; AV.AliasedFlag = isAliased; AV.OverlapFlag = mayOverlap; + AV.SanitizerCheckedFlag = isChecked; return AV; } @@ -532,9 +542,10 @@ public: NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, - IsZeroed_t isZeroed = IsNotZeroed) { + IsZeroed_t isZeroed = IsNotZeroed, + IsSanitizerChecked_t isChecked = IsNotSanitizerChecked) { return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, needsGC, - isAliased, mayOverlap, isZeroed); + isAliased, mayOverlap, isZeroed, isChecked); } IsDestructed_t isExternallyDestructed() const { @@ -553,7 +564,7 @@ public: void setVolatile(bool flag) { Quals.setVolatile(flag); } - + Qualifiers::ObjCLifetime getObjCLifetime() const { return Quals.getObjCLifetime(); } @@ -586,6 +597,10 @@ public: return Overlap_t(OverlapFlag); } + bool isSanitizerChecked() const { + return SanitizerCheckedFlag; + } + RValue asRValue() const { if (isIgnored()) { return RValue::getIgnored(); diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 7ca55070d4a0..d499364002f0 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -51,7 +51,7 @@ namespace clang { public: ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon) : CodeGenOpts(CGOpts), BackendCon(BCon) {} - + bool handleDiagnostics(const DiagnosticInfo &DI) override; bool isAnalysisRemarkEnabled(StringRef PassName) const override { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 79870ed59c96..f9e284232972 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -116,6 +116,7 @@ enum TypeEvaluationKind { SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0) \ SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0) \ SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0) \ + SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0) \ SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0) \ SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0) \ SANITIZER_CHECK(MissingReturn, missing_return, 0) \ @@ -2490,13 +2491,15 @@ public: void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E, - AggValueSlot::Overlap_t Overlap); + AggValueSlot::Overlap_t Overlap, + bool NewPointerIsChecked); void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, CallArgList &Args, AggValueSlot::Overlap_t Overlap, - SourceLocation Loc); + SourceLocation Loc, + bool NewPointerIsChecked); /// Emit assumption load for all bases. Requires to be be called only on /// most-derived class and not under construction of the object. @@ -2513,12 +2516,14 @@ public: const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, + bool NewPointerIsChecked, bool ZeroInitialization = false); void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, llvm::Value *NumElements, Address ArrayPtr, const CXXConstructExpr *E, + bool NewPointerIsChecked, bool ZeroInitialization = false); static Destroyer destroyCXXObject; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index ecdf78d4b347..8c5e0df0969b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1431,7 +1431,7 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, F->addAttributes(llvm::AttributeList::FunctionIndex, Attrs); } } - + if (const auto *CSA = D->getAttr<CodeSegAttr>()) GO->setSection(CSA->getName()); else if (const auto *SA = D->getAttr<SectionAttr>()) @@ -3176,6 +3176,10 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) { return LangAS::cuda_constant; else if (D && D->hasAttr<CUDASharedAttr>()) return LangAS::cuda_shared; + else if (D && D->hasAttr<CUDADeviceAttr>()) + return LangAS::cuda_device; + else if (D && D->getType().isConstQualified()) + return LangAS::cuda_constant; else return LangAS::cuda_device; } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index ee64ed4f2ae2..91f3d94330f1 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -280,14 +280,14 @@ private: llvm::LLVMContext &VMContext; std::unique_ptr<CodeGenTBAA> TBAA; - + mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo; - + // This should not be moved earlier, since its initialization depends on some // of the previous reference members being already initialized and also checks // if TheTargetCodeGenInfo is NULL CodeGenTypes Types; - + /// Holds information about C++ vtables. CodeGenVTables VTables; @@ -415,7 +415,7 @@ private: /// order. Once the decl is emitted, the index is replaced with ~0U to ensure /// that we don't re-emit the initializer. llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition; - + typedef std::pair<OrderGlobalInits, llvm::Function*> GlobalInitData; struct GlobalInitPriorityCmp { @@ -452,7 +452,7 @@ private: /// The type used to describe the state of a fast enumeration in /// Objective-C's for..in loop. QualType ObjCFastEnumerationStateType; - + /// @} /// Lazily create the Objective-C runtime @@ -576,7 +576,7 @@ public: llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { return StaticLocalDeclMap[D]; } - void setStaticLocalDeclAddress(const VarDecl *D, + void setStaticLocalDeclAddress(const VarDecl *D, llvm::Constant *C) { StaticLocalDeclMap[D] = C; } @@ -588,7 +588,7 @@ public: llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) { return StaticLocalDeclGuardMap[D]; } - void setStaticLocalDeclGuardAddress(const VarDecl *D, + void setStaticLocalDeclGuardAddress(const VarDecl *D, llvm::GlobalVariable *C) { StaticLocalDeclGuardMap[D] = C; } @@ -649,10 +649,10 @@ public: bool shouldUseTBAA() const { return TBAA != nullptr; } - const TargetCodeGenInfo &getTargetCodeGenInfo(); - + const TargetCodeGenInfo &getTargetCodeGenInfo(); + CodeGenTypes &getTypes() { return Types; } - + CodeGenVTables &getVTables() { return VTables; } ItaniumVTableContext &getItaniumVTableContext() { @@ -852,7 +852,7 @@ public: /// Fetches the global unique block count. int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } - + /// Fetches the type of a generic block descriptor. llvm::Type *getBlockDescriptorType(); @@ -871,7 +871,7 @@ public: /// Notes that BE's global block is available via Addr. Asserts that BE /// isn't already emitted. void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr); - + /// Return a pointer to a constant CFString object for the given string. ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); @@ -1139,7 +1139,7 @@ public: /// Return the store size, in character units, of the given LLVM type. CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; - + /// Returns LLVM linkage for a declarator. llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage, @@ -1316,7 +1316,7 @@ private: void emitCPUDispatchDefinition(GlobalDecl GD); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); void EmitObjCIvarInitializations(ObjCImplementationDecl *D); - + // C++ related functions. void EmitDeclContext(const DeclContext *DC); diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 16ec1dd301aa..1a1395e6ae74 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -54,7 +54,7 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD, SmallString<256> TypeName; llvm::raw_svector_ostream OS(TypeName); OS << RD->getKindName() << '.'; - + // Name the codegen type after the typedef name // if there is no tag type name available if (RD->getIdentifier()) { @@ -100,7 +100,7 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) { /// isRecordLayoutComplete - Return true if the specified type is already /// completely laid out. bool CodeGenTypes::isRecordLayoutComplete(const Type *Ty) const { - llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I = + llvm::DenseMap<const Type*, llvm::StructType *>::const_iterator I = RecordDeclTypes.find(Ty); return I != RecordDeclTypes.end() && !I->second->isOpaque(); } @@ -113,7 +113,7 @@ isSafeToConvert(QualType T, CodeGenTypes &CGT, /// isSafeToConvert - Return true if it is safe to convert the specified record /// decl to IR and lay it out, false if doing so would cause us to get into a /// recursive compilation mess. -static bool +static bool isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT, llvm::SmallPtrSet<const RecordDecl*, 16> &AlreadyChecked) { // If we have already checked this type (maybe the same type is used by-value @@ -122,14 +122,14 @@ isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT, return true; const Type *Key = CGT.getContext().getTagDeclType(RD).getTypePtr(); - + // If this type is already laid out, converting it is a noop. if (CGT.isRecordLayoutComplete(Key)) return true; - + // If this type is currently being laid out, we can't recursively compile it. if (CGT.isRecordBeingLaidOut(Key)) return false; - + // If this type would require laying out bases that are currently being laid // out, don't do it. This includes virtual base classes which get laid out // when a class is translated, even though they aren't embedded by-value into @@ -140,13 +140,13 @@ isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT, CGT, AlreadyChecked)) return false; } - + // If this type would require laying out members that are currently being laid // out, don't do it. for (const auto *I : RD->fields()) if (!isSafeToConvert(I->getType(), CGT, AlreadyChecked)) return false; - + // If there are no problems, lets do it. return true; } @@ -170,7 +170,7 @@ isSafeToConvert(QualType T, CodeGenTypes &CGT, return isSafeToConvert(AT->getElementType(), CGT, AlreadyChecked); // Otherwise, there is no concern about transforming this. We only care about - // things that are contained by-value in a structure that can have another + // things that are contained by-value in a structure that can have another // structure as a member. return true; } @@ -182,7 +182,7 @@ isSafeToConvert(QualType T, CodeGenTypes &CGT, static bool isSafeToConvert(const RecordDecl *RD, CodeGenTypes &CGT) { // If no structs are being laid out, we can certainly do this one. if (CGT.noRecordsBeingLaidOut()) return true; - + llvm::SmallPtrSet<const RecordDecl*, 16> AlreadyChecked; return isSafeToConvert(RD, CGT, AlreadyChecked); } @@ -229,7 +229,7 @@ bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) { bool CodeGenTypes::isFuncTypeConvertible(const FunctionType *FT) { if (!isFuncParamTypeConvertible(FT->getReturnType())) return false; - + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++) if (!isFuncParamTypeConvertible(FPT->getParamType(i))) @@ -259,7 +259,7 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) { DI->completeType(ED); return; } - + // If we completed a RecordDecl that we previously used and converted to an // anonymous type, then go ahead and complete it now. const RecordDecl *RD = cast<RecordDecl>(TD); @@ -388,7 +388,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { // RecordTypes are cached and processed specially. if (const RecordType *RT = dyn_cast<RecordType>(Ty)) return ConvertRecordDeclType(RT->getDecl()); - + // See if type is already cached. llvm::DenseMap<const Type *, llvm::Type *>::iterator TCI = TypeCache.find(Ty); // If type is found in map then use it. Otherwise, convert type T. @@ -494,7 +494,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { // Model std::nullptr_t as i8* ResultType = llvm::Type::getInt8PtrTy(getLLVMContext()); break; - + case BuiltinType::UInt128: case BuiltinType::Int128: ResultType = llvm::IntegerType::get(getLLVMContext(), 128); @@ -510,7 +510,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::OCLReserveID: ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); break; - + case BuiltinType::Dependent: #define BUILTIN_TYPE(Id, SingletonId) #define PLACEHOLDER_TYPE(Id, SingletonId) \ @@ -574,8 +574,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case Type::ConstantArray: { const ConstantArrayType *A = cast<ConstantArrayType>(Ty); llvm::Type *EltTy = ConvertTypeForMem(A->getElementType()); - - // Lower arrays of undefined struct type to arrays of i8 just to have a + + // Lower arrays of undefined struct type to arrays of i8 just to have a // concrete type. if (!EltTy->isSized()) { SkippedLayout = true; @@ -674,9 +674,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { break; } } - + assert(ResultType && "Didn't convert a type?"); - + TypeCache[Ty] = ResultType; return ResultType; } @@ -709,7 +709,7 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { RD = RD->getDefinition(); if (!RD || !RD->isCompleteDefinition() || !Ty->isOpaque()) return Ty; - + // If converting this type would cause us to infinitely loop, don't do it! if (!isSafeToConvert(RD, *this)) { DeferredRecords.push_back(RD); @@ -720,12 +720,12 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { bool InsertResult = RecordsBeingLaidOut.insert(Key).second; (void)InsertResult; assert(InsertResult && "Recursively compiling a struct?"); - + // Force conversion of non-virtual base classes recursively. if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { for (const auto &I : CRD->bases()) { if (I.isVirtual()) continue; - + ConvertRecordDeclType(I.getType()->getAs<RecordType>()->getDecl()); } } @@ -737,13 +737,13 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) { // We're done laying out this struct. bool EraseResult = RecordsBeingLaidOut.erase(Key); (void)EraseResult; assert(EraseResult && "struct not in RecordsBeingLaidOut set?"); - + // If this struct blocked a FunctionType conversion, then recompute whatever // was derived from that. // FIXME: This is hugely overconservative. if (SkippedLayout) TypeCache.clear(); - + // If we're done converting the outer-most record, then convert any deferred // structs as well. if (RecordsBeingLaidOut.empty()) @@ -799,7 +799,7 @@ bool CodeGenTypes::isZeroInitializable(QualType T) { // We have to ask the ABI about member pointers. if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) return getCXXABI().isZeroInitializable(MPT); - + // Everything else is okay. return true; } diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index fb8d31684290..626869f00021 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -140,7 +140,7 @@ class CodeGenTypes { /// Contains the LLVM IR type for any converted RecordDecl. llvm::DenseMap<const Type*, llvm::StructType *> RecordDeclTypes; - + /// Hold memoized CGFunctionInfo results. llvm::FoldingSet<CGFunctionInfo> FunctionInfos; @@ -149,15 +149,15 @@ class CodeGenTypes { /// struct A { struct B { int x; } } when processing 'x', the 'A' and 'B' /// types will be in this set. llvm::SmallPtrSet<const Type*, 4> RecordsBeingLaidOut; - + llvm::SmallPtrSet<const CGFunctionInfo*, 4> FunctionsBeingProcessed; - + /// True if we didn't layout a function due to a being inside /// a recursive struct conversion, set this to true. bool SkippedLayout; SmallVector<const RecordDecl *, 8> DeferredRecords; - + /// This map keeps cache of llvm::Types and maps clang::Type to /// corresponding llvm::Type. llvm::DenseMap<const Type *, llvm::Type *> TypeCache; @@ -343,7 +343,7 @@ public: /// optional suffix and name the given LLVM type using it. void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, StringRef suffix); - + public: // These are internal details of CGT that shouldn't be used externally. /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union. @@ -365,7 +365,7 @@ public: // These are internal details of CGT that shouldn't be used externally. /// IsZeroInitializable - Return whether a record type can be /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. bool isZeroInitializable(const RecordDecl *RD); - + bool isRecordLayoutComplete(const Type *Ty) const; bool noRecordsBeingLaidOut() const { return RecordsBeingLaidOut.empty(); @@ -373,7 +373,7 @@ public: // These are internal details of CGT that shouldn't be used externally. bool isRecordBeingLaidOut(const Type *Ty) const { return RecordsBeingLaidOut.count(Ty); } - + }; } // end namespace CodeGen diff --git a/lib/CodeGen/ConstantInitBuilder.cpp b/lib/CodeGen/ConstantInitBuilder.cpp index 7f8d80985032..59e66b88fb01 100644 --- a/lib/CodeGen/ConstantInitBuilder.cpp +++ b/lib/CodeGen/ConstantInitBuilder.cpp @@ -166,7 +166,7 @@ void ConstantAggregateBuilderBase::getGEPIndicesTo( if (Parent) { Parent->getGEPIndicesTo(indices, Begin); - // Otherwise, add an index to drill into the first level of pointer. + // Otherwise, add an index to drill into the first level of pointer. } else { assert(indices.empty()); indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0)); diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 16fdd1c16a1d..00fff144b597 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -3744,22 +3744,12 @@ static StructorCodegen getCodegenToUse(CodeGenModule &CGM, } llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl); - // All discardable structors can be RAUWed, but we don't want to do that in - // unoptimized code, as that makes complete structor symbol disappear - // completely, which degrades debugging experience. - // Symbols with private linkage can be safely aliased, so we special case them - // here. - if (llvm::GlobalValue::isLocalLinkage(Linkage)) - return CGM.getCodeGenOpts().OptimizationLevel > 0 ? StructorCodegen::RAUW - : StructorCodegen::Alias; + if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) + return StructorCodegen::RAUW; - // Linkonce structors cannot be aliased nor placed in a comdat, so these need - // to be emitted separately. // FIXME: Should we allow available_externally aliases? - if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) || - !llvm::GlobalAlias::isValidLinkage(Linkage)) - return CGM.getCodeGenOpts().OptimizationLevel > 0 ? StructorCodegen::RAUW - : StructorCodegen::Emit; + if (!llvm::GlobalAlias::isValidLinkage(Linkage)) + return StructorCodegen::RAUW; if (llvm::GlobalValue::isWeakForLinker(Linkage)) { // Only ELF and wasm support COMDATs with arbitrary names (C5/D5). diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 81ed05059546..059adb78ca30 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -165,7 +165,7 @@ public: llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD) override; - + llvm::BasicBlock * EmitDtorCompleteObjectHandler(CodeGenFunction &CGF); @@ -1123,7 +1123,7 @@ MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) { CGF.EmitBlock(CallVbaseDtorsBB); // CGF will put the base dtor calls in this basic block for us later. - + return SkipVbaseDtorsBB; } @@ -1393,7 +1393,7 @@ Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall( Address Result = This; if (ML.VBase) { Result = CGF.Builder.CreateElementBitCast(Result, CGF.Int8Ty); - + const CXXRecordDecl *Derived = MD->getParent(); const CXXRecordDecl *VBase = ML.VBase; llvm::Value *VBaseOffset = @@ -1562,21 +1562,21 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD, Type), This, false); } - + llvm::BasicBlock *BaseDtorEndBB = nullptr; if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.CurCodeDecl)) { BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF); - } + } CGF.EmitCXXDestructorCall(DD, Callee, This.getPointer(), /*ImplicitParam=*/nullptr, /*ImplicitParamTy=*/QualType(), nullptr, getFromDtorType(Type)); if (BaseDtorEndBB) { - // Complete object handler should continue to be the remaining + // Complete object handler should continue to be the remaining CGF.Builder.CreateBr(BaseDtorEndBB); CGF.EmitBlock(BaseDtorEndBB); - } + } } void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info, diff --git a/lib/CodeGen/SwiftCallingConv.cpp b/lib/CodeGen/SwiftCallingConv.cpp index 3673a5597eac..b411a501ea81 100644 --- a/lib/CodeGen/SwiftCallingConv.cpp +++ b/lib/CodeGen/SwiftCallingConv.cpp @@ -163,7 +163,7 @@ void SwiftAggLowering::addTypedData(const RecordDecl *record, CharUnits begin, // - virtual bases for (auto &vbaseSpecifier : cxxRecord->vbases()) { auto baseRecord = vbaseSpecifier.getType()->getAsCXXRecordDecl(); - addTypedData(baseRecord, begin + layout.getVBaseClassOffset(baseRecord)); + addTypedData(baseRecord, begin + layout.getVBaseClassOffset(baseRecord)); } } } @@ -583,7 +583,7 @@ bool SwiftAggLowering::shouldPassIndirectly(bool asReturnValue) const { if (Entries.size() == 1) { return getSwiftABIInfo(CGM).shouldPassIndirectlyForSwift( Entries.back().Type, - asReturnValue); + asReturnValue); } SmallVector<llvm::Type*, 8> componentTys; diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index fa9b0a27af28..6f6c5f50c2e7 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -305,7 +305,7 @@ static Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Addr = Address(emitRoundPointerUpToAlignment(CGF, Ptr, DirectAlign), DirectAlign); } else { - Addr = Address(Ptr, SlotSize); + Addr = Address(Ptr, SlotSize); } // Advance the pointer past the argument, then store that back. @@ -369,7 +369,7 @@ static Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, } return Addr; - + } static Address emitMergePHI(CodeGenFunction &CGF, @@ -1014,7 +1014,7 @@ class X86_32ABIInfo : public SwiftABIInfo { ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const; ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const; - /// Updates the number of available free registers, returns + /// Updates the number of available free registers, returns /// true if any registers were allocated. bool updateFreeRegs(QualType Ty, CCState &State) const; @@ -1044,7 +1044,7 @@ public: bool RetSmallStructInRegABI, bool Win32StructABI, unsigned NumRegisterParameters, bool SoftFloatABI) : SwiftABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI), - IsRetSmallStructInRegABI(RetSmallStructInRegABI), + IsRetSmallStructInRegABI(RetSmallStructInRegABI), IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI), IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()), @@ -1057,7 +1057,7 @@ public: // four vector registers for vectors, but those can overlap with the // scalar registers. return occupiesMoreThan(CGT, scalars, /*total*/ 3); - } + } bool isSwiftErrorInRegister() const override { // x86-32 lowering does not support passing swifterror in a register. @@ -1546,7 +1546,7 @@ bool X86_32ABIInfo::updateFreeRegs(QualType Ty, CCState &State) const { return true; } -bool X86_32ABIInfo::shouldAggregateUseDirect(QualType Ty, CCState &State, +bool X86_32ABIInfo::shouldAggregateUseDirect(QualType Ty, CCState &State, bool &InReg, bool &NeedsPadding) const { // On Windows, aggregates other than HFAs are never passed in registers, and @@ -1589,7 +1589,7 @@ bool X86_32ABIInfo::shouldPrimitiveUseInReg(QualType Ty, CCState &State) const { if (getContext().getTypeSize(Ty) > 32) return false; - return (Ty->isIntegralOrEnumerationType() || Ty->isPointerType() || + return (Ty->isIntegralOrEnumerationType() || Ty->isPointerType() || Ty->isReferenceType()); } @@ -2185,7 +2185,7 @@ public: bool shouldPassIndirectlyForSwift(ArrayRef<llvm::Type*> scalars, bool asReturnValue) const override { return occupiesMoreThan(CGT, scalars, /*total*/ 4); - } + } bool isSwiftErrorInRegister() const override { return true; } @@ -3785,7 +3785,7 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, CGF.Builder.CreateMemCpy(Tmp, RegAddr, TySize, false); RegAddr = Tmp; } - + } else if (neededSSE == 1) { RegAddr = Address(CGF.Builder.CreateGEP(RegSaveArea, fp_offset), CharUnits::fromQuantity(16)); @@ -4180,7 +4180,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, } // Get the address of the saved value by scaling the number of - // registers we've used by the number of + // registers we've used by the number of CharUnits RegSize = CharUnits::fromQuantity((isInt || IsSoftFloatABI) ? 4 : 8); llvm::Value *RegOffset = Builder.CreateMul(NumRegs, Builder.getInt8(RegSize.getQuantity())); @@ -4191,7 +4191,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // Increase the used-register count. NumRegs = - Builder.CreateAdd(NumRegs, + Builder.CreateAdd(NumRegs, Builder.getInt8((isI64 || (isF64 && IsSoftFloatABI)) ? 2 : 1)); Builder.CreateStore(NumRegs, NumRegsAddr); @@ -4227,7 +4227,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, OverflowArea = Address(emitRoundPointerUpToAlignment(CGF, Ptr, Align), Align); } - + MemAddr = Builder.CreateElementBitCast(OverflowArea, DirectTy); // Increase the overflow area. @@ -5063,7 +5063,13 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const { if (getTarget().isRenderScriptTarget()) { return coerceToIntArray(Ty, getContext(), getVMContext()); } - unsigned Alignment = getContext().getTypeAlign(Ty); + unsigned Alignment; + if (Kind == AArch64ABIInfo::AAPCS) { + Alignment = getContext().getTypeUnadjustedAlign(Ty); + Alignment = Alignment < 128 ? 64 : 128; + } else { + Alignment = getContext().getTypeAlign(Ty); + } Size = llvm::alignTo(Size, 64); // round up to multiple of 8 bytes // We use a pair of i64 for 16-byte aggregate with 8-byte alignment. @@ -5801,11 +5807,14 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, // most 8-byte. We realign the indirect argument if type alignment is bigger // than ABI alignment. uint64_t ABIAlign = 4; - uint64_t TyAlign = getContext().getTypeAlign(Ty) / 8; + uint64_t TyAlign; if (getABIKind() == ARMABIInfo::AAPCS_VFP || - getABIKind() == ARMABIInfo::AAPCS) + getABIKind() == ARMABIInfo::AAPCS) { + TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity(); ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8); - + } else { + TyAlign = getContext().getTypeAlignInChars(Ty).getQuantity(); + } if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) { assert(getABIKind() != ARMABIInfo::AAPCS16_VFP && "unexpected byval"); return ABIArgInfo::getIndirect(CharUnits::fromQuantity(ABIAlign), @@ -5824,7 +5833,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, unsigned SizeRegs; // FIXME: Try to match the types of the arguments more accurately where // we can. - if (getContext().getTypeAlign(Ty) <= 32) { + if (TyAlign <= 4) { ElemTy = llvm::Type::getInt32Ty(getVMContext()); SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32; } else { @@ -6985,8 +6994,14 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) RetTy = EnumTy->getDecl()->getIntegerType(); - return (RetTy->isPromotableIntegerType() ? ABIArgInfo::getExtend(RetTy) - : ABIArgInfo::getDirect()); + if (RetTy->isPromotableIntegerType()) + return ABIArgInfo::getExtend(RetTy); + + if ((RetTy->isUnsignedIntegerOrEnumerationType() || + RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32) + return ABIArgInfo::getSignExtend(RetTy); + + return ABIArgInfo::getDirect(); } void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { |