diff options
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGExprCXX.cpp | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 8955d8a4a83c9..f29ef754c03f4 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"); |