@@ -744,111 +744,116 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
744744 if (Ty.isVolatileQualified ())
745745 return ;
746746
747- auto CheckHandler = SanitizerHandler::TypeMismatch;
748- // SO_Vptr's corresponding handler is DynamicTypeCacheMiss, not TypeMismatch.
749- // However, it relies upon IsGuaranteedNonNull, hence the instructions cannot
750- // be fully separated from the TypeMismatch.
751- SanitizerDebugLocation SanScope (
752- this ,
753- {SanitizerKind::SO_Null, SanitizerKind::SO_ObjectSize,
754- SanitizerKind::SO_Alignment, SanitizerKind::SO_Vptr},
755- CheckHandler);
756-
757- SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3 >
758- Checks;
759- llvm::BasicBlock *Done = nullptr ;
760-
761747 // Quickly determine whether we have a pointer to an alloca. It's possible
762748 // to skip null checks, and some alignment checks, for these pointers. This
763749 // can reduce compile-time significantly.
764750 auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts ());
765751
766- llvm::Value *True = llvm::ConstantInt::getTrue (getLLVMContext ());
767752 llvm::Value *IsNonNull = nullptr ;
768753 bool IsGuaranteedNonNull =
769754 SkippedChecks.has (SanitizerKind::Null) || PtrToAlloca;
770- bool AllowNullPointers = isNullPointerAllowed (TCK);
771- if ((SanOpts.has (SanitizerKind::Null) || AllowNullPointers) &&
772- !IsGuaranteedNonNull) {
773- // The glvalue must not be an empty glvalue.
774- IsNonNull = Builder.CreateIsNotNull (Ptr);
775755
776- // The IR builder can constant-fold the null check if the pointer points to
777- // a constant.
778- IsGuaranteedNonNull = IsNonNull == True;
779-
780- // Skip the null check if the pointer is known to be non-null.
781- if (!IsGuaranteedNonNull) {
782- if (AllowNullPointers) {
783- // When performing pointer casts, it's OK if the value is null.
784- // Skip the remaining checks in that case.
785- Done = createBasicBlock (" null" );
786- llvm::BasicBlock *Rest = createBasicBlock (" not.null" );
787- Builder.CreateCondBr (IsNonNull, Rest, Done);
788- EmitBlock (Rest);
789- } else {
790- Checks.push_back (std::make_pair (IsNonNull, SanitizerKind::SO_Null));
756+ llvm::BasicBlock *Done = nullptr ;
757+ bool DoneViaNullSanitize = false ;
758+
759+ {
760+ auto CheckHandler = SanitizerHandler::TypeMismatch;
761+ SanitizerDebugLocation SanScope (this ,
762+ {SanitizerKind::SO_Null,
763+ SanitizerKind::SO_ObjectSize,
764+ SanitizerKind::SO_Alignment},
765+ CheckHandler);
766+
767+ SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 3 >
768+ Checks;
769+
770+ llvm::Value *True = llvm::ConstantInt::getTrue (getLLVMContext ());
771+ bool AllowNullPointers = isNullPointerAllowed (TCK);
772+ if ((SanOpts.has (SanitizerKind::Null) || AllowNullPointers) &&
773+ !IsGuaranteedNonNull) {
774+ // The glvalue must not be an empty glvalue.
775+ IsNonNull = Builder.CreateIsNotNull (Ptr);
776+
777+ // The IR builder can constant-fold the null check if the pointer points
778+ // to a constant.
779+ IsGuaranteedNonNull = IsNonNull == True;
780+
781+ // Skip the null check if the pointer is known to be non-null.
782+ if (!IsGuaranteedNonNull) {
783+ if (AllowNullPointers) {
784+ // When performing pointer casts, it's OK if the value is null.
785+ // Skip the remaining checks in that case.
786+ Done = createBasicBlock (" null" );
787+ DoneViaNullSanitize = true ;
788+ llvm::BasicBlock *Rest = createBasicBlock (" not.null" );
789+ Builder.CreateCondBr (IsNonNull, Rest, Done);
790+ EmitBlock (Rest);
791+ } else {
792+ Checks.push_back (std::make_pair (IsNonNull, SanitizerKind::SO_Null));
793+ }
791794 }
792795 }
793- }
794796
795- if (SanOpts.has (SanitizerKind::ObjectSize) &&
796- !SkippedChecks.has (SanitizerKind::ObjectSize) &&
797- !Ty->isIncompleteType ()) {
798- uint64_t TySize = CGM.getMinimumObjectSize (Ty).getQuantity ();
799- llvm::Value *Size = llvm::ConstantInt::get (IntPtrTy, TySize);
800- if (ArraySize)
801- Size = Builder.CreateMul (Size, ArraySize);
802-
803- // Degenerate case: new X[0] does not need an objectsize check.
804- llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
805- if (!ConstantSize || !ConstantSize->isNullValue ()) {
806- // The glvalue must refer to a large enough storage region.
807- // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation
808- // to check this.
809- // FIXME: Get object address space
810- llvm::Type *Tys[2 ] = { IntPtrTy, Int8PtrTy };
811- llvm::Function *F = CGM.getIntrinsic (llvm::Intrinsic::objectsize, Tys);
812- llvm::Value *Min = Builder.getFalse ();
813- llvm::Value *NullIsUnknown = Builder.getFalse ();
814- llvm::Value *Dynamic = Builder.getFalse ();
815- llvm::Value *LargeEnough = Builder.CreateICmpUGE (
816- Builder.CreateCall (F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
817- Checks.push_back (
818- std::make_pair (LargeEnough, SanitizerKind::SO_ObjectSize));
797+ if (SanOpts.has (SanitizerKind::ObjectSize) &&
798+ !SkippedChecks.has (SanitizerKind::ObjectSize) &&
799+ !Ty->isIncompleteType ()) {
800+ uint64_t TySize = CGM.getMinimumObjectSize (Ty).getQuantity ();
801+ llvm::Value *Size = llvm::ConstantInt::get (IntPtrTy, TySize);
802+ if (ArraySize)
803+ Size = Builder.CreateMul (Size, ArraySize);
804+
805+ // Degenerate case: new X[0] does not need an objectsize check.
806+ llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
807+ if (!ConstantSize || !ConstantSize->isNullValue ()) {
808+ // The glvalue must refer to a large enough storage region.
809+ // FIXME: If Address Sanitizer is enabled, insert dynamic
810+ // instrumentation
811+ // to check this.
812+ // FIXME: Get object address space
813+ llvm::Type *Tys[2 ] = {IntPtrTy, Int8PtrTy};
814+ llvm::Function *F = CGM.getIntrinsic (llvm::Intrinsic::objectsize, Tys);
815+ llvm::Value *Min = Builder.getFalse ();
816+ llvm::Value *NullIsUnknown = Builder.getFalse ();
817+ llvm::Value *Dynamic = Builder.getFalse ();
818+ llvm::Value *LargeEnough = Builder.CreateICmpUGE (
819+ Builder.CreateCall (F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
820+ Checks.push_back (
821+ std::make_pair (LargeEnough, SanitizerKind::SO_ObjectSize));
822+ }
819823 }
820- }
821824
822- llvm::MaybeAlign AlignVal;
823- llvm::Value *PtrAsInt = nullptr ;
824-
825- if (SanOpts.has (SanitizerKind::Alignment) &&
826- !SkippedChecks.has (SanitizerKind::Alignment)) {
827- AlignVal = Alignment.getAsMaybeAlign ();
828- if (!Ty->isIncompleteType () && !AlignVal)
829- AlignVal = CGM.getNaturalTypeAlignment (Ty, nullptr , nullptr ,
830- /* ForPointeeType=*/ true )
831- .getAsMaybeAlign ();
832-
833- // The glvalue must be suitably aligned.
834- if (AlignVal && *AlignVal > llvm::Align (1 ) &&
835- (!PtrToAlloca || PtrToAlloca->getAlign () < *AlignVal)) {
836- PtrAsInt = Builder.CreatePtrToInt (Ptr, IntPtrTy);
837- llvm::Value *Align = Builder.CreateAnd (
838- PtrAsInt, llvm::ConstantInt::get (IntPtrTy, AlignVal->value () - 1 ));
839- llvm::Value *Aligned =
840- Builder.CreateICmpEQ (Align, llvm::ConstantInt::get (IntPtrTy, 0 ));
841- if (Aligned != True)
842- Checks.push_back (std::make_pair (Aligned, SanitizerKind::SO_Alignment));
825+ llvm::MaybeAlign AlignVal;
826+ llvm::Value *PtrAsInt = nullptr ;
827+
828+ if (SanOpts.has (SanitizerKind::Alignment) &&
829+ !SkippedChecks.has (SanitizerKind::Alignment)) {
830+ AlignVal = Alignment.getAsMaybeAlign ();
831+ if (!Ty->isIncompleteType () && !AlignVal)
832+ AlignVal = CGM.getNaturalTypeAlignment (Ty, nullptr , nullptr ,
833+ /* ForPointeeType=*/ true )
834+ .getAsMaybeAlign ();
835+
836+ // The glvalue must be suitably aligned.
837+ if (AlignVal && *AlignVal > llvm::Align (1 ) &&
838+ (!PtrToAlloca || PtrToAlloca->getAlign () < *AlignVal)) {
839+ PtrAsInt = Builder.CreatePtrToInt (Ptr, IntPtrTy);
840+ llvm::Value *Align = Builder.CreateAnd (
841+ PtrAsInt, llvm::ConstantInt::get (IntPtrTy, AlignVal->value () - 1 ));
842+ llvm::Value *Aligned =
843+ Builder.CreateICmpEQ (Align, llvm::ConstantInt::get (IntPtrTy, 0 ));
844+ if (Aligned != True)
845+ Checks.push_back (
846+ std::make_pair (Aligned, SanitizerKind::SO_Alignment));
847+ }
843848 }
844- }
845849
846- if (Checks.size () > 0 ) {
847- llvm::Constant *StaticData[] = {
848- EmitCheckSourceLocation (Loc), EmitCheckTypeDescriptor (Ty),
849- llvm::ConstantInt::get (Int8Ty, AlignVal ? llvm::Log2 (*AlignVal) : 1 ),
850- llvm::ConstantInt::get (Int8Ty, TCK)};
851- EmitCheck (Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
850+ if (Checks.size () > 0 ) {
851+ llvm::Constant *StaticData[] = {
852+ EmitCheckSourceLocation (Loc), EmitCheckTypeDescriptor (Ty),
853+ llvm::ConstantInt::get (Int8Ty, AlignVal ? llvm::Log2 (*AlignVal) : 1 ),
854+ llvm::ConstantInt::get (Int8Ty, TCK)};
855+ EmitCheck (Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
856+ }
852857 }
853858
854859 // If possible, check that the vptr indicates that there is a subobject of
@@ -861,6 +866,9 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
861866 // or call a non-static member function
862867 if (SanOpts.has (SanitizerKind::Vptr) &&
863868 !SkippedChecks.has (SanitizerKind::Vptr) && isVptrCheckRequired (TCK, Ty)) {
869+ SanitizerDebugLocation SanScope (this , {SanitizerKind::SO_Vptr},
870+ SanitizerHandler::DynamicTypeCacheMiss);
871+
864872 // Ensure that the pointer is non-null before loading it. If there is no
865873 // compile-time guarantee, reuse the run-time null check or emit a new one.
866874 if (!IsGuaranteedNonNull) {
@@ -929,6 +937,11 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
929937 }
930938
931939 if (Done) {
940+ SanitizerDebugLocation SanScope (
941+ this ,
942+ {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
943+ DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
944+ : SanitizerHandler::DynamicTypeCacheMiss);
932945 Builder.CreateBr (Done);
933946 EmitBlock (Done);
934947 }
0 commit comments