@@ -3614,29 +3614,33 @@ void CodeGenFunction::EmitCheck(
36143614 llvm::Value *RecoverableCond = nullptr ;
36153615 llvm::Value *TrapCond = nullptr ;
36163616 bool NoMerge = false ;
3617+ // Expand checks into:
3618+ // (Check1 || !allow_ubsan_check) && (Check2 || !allow_ubsan_check) ...
3619+ // We need separate allow_ubsan_check intrinsics because they have separately
3620+ // specified cutoffs.
3621+ // This expression looks expensive but will be simplified after
3622+ // LowerAllowCheckPass.
36173623 for (auto &[Check, Ord] : Checked) {
3624+ llvm::Value *GuardedCheck = Check;
3625+ if (ClSanitizeGuardChecks ||
3626+ (CGM.getCodeGenOpts ().SanitizeSkipHotCutoffs [Ord] > 0 )) {
3627+ llvm::Value *Allow = Builder.CreateCall (
3628+ CGM.getIntrinsic (llvm::Intrinsic::allow_ubsan_check),
3629+ llvm::ConstantInt::get (CGM.Int8Ty , Ord));
3630+ GuardedCheck = Builder.CreateOr (Check, Builder.CreateNot (Allow));
3631+ }
3632+
36183633 // -fsanitize-trap= overrides -fsanitize-recover=.
36193634 llvm::Value *&Cond = CGM.getCodeGenOpts ().SanitizeTrap .has (Ord) ? TrapCond
36203635 : CGM.getCodeGenOpts ().SanitizeRecover .has (Ord)
36213636 ? RecoverableCond
36223637 : FatalCond;
3623- Cond = Cond ? Builder.CreateAnd (Cond, Check ) : Check ;
3638+ Cond = Cond ? Builder.CreateAnd (Cond, GuardedCheck ) : GuardedCheck ;
36243639
36253640 if (!CGM.getCodeGenOpts ().SanitizeMergeHandlers .has (Ord))
36263641 NoMerge = true ;
36273642 }
36283643
3629- if (ClSanitizeGuardChecks) {
3630- llvm::Value *Allow =
3631- Builder.CreateCall (CGM.getIntrinsic (llvm::Intrinsic::allow_ubsan_check),
3632- llvm::ConstantInt::get (CGM.Int8Ty , CheckHandler));
3633-
3634- for (llvm::Value **Cond : {&FatalCond, &RecoverableCond, &TrapCond}) {
3635- if (*Cond)
3636- *Cond = Builder.CreateOr (*Cond, Builder.CreateNot (Allow));
3637- }
3638- }
3639-
36403644 if (TrapCond)
36413645 EmitTrapCheck (TrapCond, CheckHandler, NoMerge);
36423646 if (!FatalCond && !RecoverableCond)
0 commit comments