diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 100 |
1 files changed, 72 insertions, 28 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 111b5805c6a9..193710bef2d1 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -999,7 +999,9 @@ void ScalarExprEmitter::EmitFloatConversionCheck( if (!isa<llvm::IntegerType>(DstTy)) return; - CodeGenFunction::SanitizerScope SanScope(&CGF); + auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow; + auto CheckHandler = SanitizerHandler::FloatCastOverflow; + SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler); using llvm::APFloat; using llvm::APSInt; @@ -1056,8 +1058,8 @@ void ScalarExprEmitter::EmitFloatConversionCheck( llvm::Constant *StaticArgs[] = {CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(OrigSrcType), CGF.EmitCheckTypeDescriptor(DstType)}; - CGF.EmitCheck(std::make_pair(Check, SanitizerKind::SO_FloatCastOverflow), - SanitizerHandler::FloatCastOverflow, StaticArgs, OrigSrc); + CGF.EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs, + OrigSrc); } // Should be called within CodeGenFunction::SanitizerScope RAII scope. @@ -1134,18 +1136,31 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, (!SrcSigned && DstSigned)) return; - CodeGenFunction::SanitizerScope SanScope(&CGF); - std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> - Check = - EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); - // If the comparison result is 'i1 false', then the truncation was lossy. + Check; + + auto CheckHandler = SanitizerHandler::ImplicitConversion; + { + // We don't know the check kind until we call + // EmitIntegerTruncationCheckHelper, but we want to annotate + // EmitIntegerTruncationCheckHelper's instructions too. + SanitizerDebugLocation SanScope( + &CGF, + {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation, + SanitizerKind::SO_ImplicitSignedIntegerTruncation}, + CheckHandler); + Check = + EmitIntegerTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); + // If the comparison result is 'i1 false', then the truncation was lossy. + } // Do we care about this type of truncation? if (!CGF.SanOpts.has(Check.second.second)) return; + SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler); + // Does some SSCL ignore this type? if (CGF.getContext().isTypeIgnoredBySanitizer( SanitizerMask::bitPosToMask(Check.second.second), DstType)) @@ -1157,8 +1172,7 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType, llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first), llvm::ConstantInt::get(Builder.getInt32Ty(), 0)}; - CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs, - {Src, Dst}); + CGF.EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst}); } static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType, @@ -1272,7 +1286,13 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, return; // That's it. We can't rule out any more cases with the data we have. - CodeGenFunction::SanitizerScope SanScope(&CGF); + auto CheckHandler = SanitizerHandler::ImplicitConversion; + SanitizerDebugLocation SanScope( + &CGF, + {SanitizerKind::SO_ImplicitIntegerSignChange, + SanitizerKind::SO_ImplicitUnsignedIntegerTruncation, + SanitizerKind::SO_ImplicitSignedIntegerTruncation}, + CheckHandler); std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> @@ -1308,8 +1328,7 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind), llvm::ConstantInt::get(Builder.getInt32Ty(), 0)}; // EmitCheck() will 'and' all the checks together. - CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs, - {Src, Dst}); + CGF.EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst}); } // Should be called within CodeGenFunction::SanitizerScope RAII scope. @@ -1393,7 +1412,9 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType, bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); - CodeGenFunction::SanitizerScope SanScope(this); + auto CheckHandler = SanitizerHandler::ImplicitConversion; + SanitizerDebugLocation SanScope( + this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler); std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> @@ -1439,8 +1460,7 @@ void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType, llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind), llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)}; - EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs, - {Src, Dst}); + EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst}); } Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType, @@ -3975,7 +3995,11 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { { - CodeGenFunction::SanitizerScope SanScope(&CGF); + SanitizerDebugLocation SanScope(&CGF, + {SanitizerKind::SO_IntegerDivideByZero, + SanitizerKind::SO_SignedIntegerOverflow, + SanitizerKind::SO_FloatDivideByZero}, + SanitizerHandler::DivremOverflow); if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && Ops.Ty->isIntegerType() && @@ -4029,7 +4053,10 @@ Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) { CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) && Ops.Ty->isIntegerType() && (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) { - CodeGenFunction::SanitizerScope SanScope(&CGF); + SanitizerDebugLocation SanScope(&CGF, + {SanitizerKind::SO_IntegerDivideByZero, + SanitizerKind::SO_SignedIntegerOverflow}, + SanitizerHandler::DivremOverflow); llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false); } @@ -4078,7 +4105,10 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { if (isSigned) OpID |= 1; - CodeGenFunction::SanitizerScope SanScope(&CGF); + SanitizerDebugLocation SanScope(&CGF, + {SanitizerKind::SO_SignedIntegerOverflow, + SanitizerKind::SO_UnsignedIntegerOverflow}, + OverflowKind); llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty); llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy); @@ -4204,7 +4234,9 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, PtrTy->getPointerAddressSpace())) return Ptr; // The inbounds GEP of null is valid iff the index is zero. - CodeGenFunction::SanitizerScope SanScope(&CGF); + auto CheckOrdinal = SanitizerKind::SO_PointerOverflow; + auto CheckHandler = SanitizerHandler::PointerOverflow; + SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler); Value *IsZeroIndex = CGF.Builder.CreateIsNull(index); llvm::Constant *StaticArgs[] = { CGF.EmitCheckSourceLocation(op.E->getExprLoc())}; @@ -4212,8 +4244,8 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy); Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy); Value *DynamicArgs[] = {IntPtr, ComputedGEP}; - CGF.EmitCheck({{IsZeroIndex, SanitizerKind::SO_PointerOverflow}}, - SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs); + CGF.EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs, + DynamicArgs); return Ptr; } @@ -4734,7 +4766,16 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { RHS = ConstrainShiftValue(Ops.LHS, RHS, "shl.mask"); else if ((SanitizeBase || SanitizeExponent) && isa<llvm::IntegerType>(Ops.LHS->getType())) { - CodeGenFunction::SanitizerScope SanScope(&CGF); + SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals; + if (SanitizeSignedBase) + Ordinals.push_back(SanitizerKind::SO_ShiftBase); + if (SanitizeUnsignedBase) + Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase); + if (SanitizeExponent) + Ordinals.push_back(SanitizerKind::SO_ShiftExponent); + + SanitizerDebugLocation SanScope(&CGF, Ordinals, + SanitizerHandler::ShiftOutOfBounds); SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks; bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); llvm::Value *WidthMinusOne = @@ -4805,7 +4846,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { RHS = ConstrainShiftValue(Ops.LHS, RHS, "shr.mask"); else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) && isa<llvm::IntegerType>(Ops.LHS->getType())) { - CodeGenFunction::SanitizerScope SanScope(&CGF); + SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent}, + SanitizerHandler::ShiftOutOfBounds); bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation(); llvm::Value *Valid = Builder.CreateICmpULE( Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned)); @@ -6037,7 +6079,9 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, const auto &DL = CGM.getDataLayout(); - SanitizerScope SanScope(this); + auto CheckOrdinal = SanitizerKind::SO_PointerOverflow; + auto CheckHandler = SanitizerHandler::PointerOverflow; + SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler); llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy); GEPOffsetAndOverflow EvaluatedGEP = @@ -6074,7 +6118,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr); auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP); auto *Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr); - Checks.emplace_back(Valid, SanitizerKind::SO_PointerOverflow); + Checks.emplace_back(Valid, CheckOrdinal); } if (PerformOverflowCheck) { @@ -6110,7 +6154,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr); } ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow); - Checks.emplace_back(ValidGEP, SanitizerKind::SO_PointerOverflow); + Checks.emplace_back(ValidGEP, CheckOrdinal); } assert(!Checks.empty() && "Should have produced some checks."); @@ -6118,7 +6162,7 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)}; // Pass the computed GEP to the runtime to avoid emitting poisoned arguments. llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP}; - EmitCheck(Checks, SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs); + EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs); return GEPVal; } |
