@@ -3486,7 +3486,8 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
34863486 return GV;
34873487}
34883488
3489- llvm::Value *CodeGenFunction::EmitCheckValue (llvm::Value *V) {
3489+ llvm::Value *CodeGenFunction::EmitCheckValue (llvm::Value *V,
3490+ bool &MayReadFromPtrToInt) {
34903491 llvm::Type *TargetTy = IntPtrTy;
34913492
34923493 if (V->getType () == TargetTy)
@@ -3512,6 +3513,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
35123513 Builder.CreateStore (V, Ptr);
35133514 V = Ptr.getPointer ();
35143515 }
3516+ MayReadFromPtrToInt = true ;
35153517 return Builder.CreatePtrToInt (V, TargetTy);
35163518}
35173519
@@ -3617,7 +3619,8 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
36173619 ArrayRef<llvm::Value *> FnArgs,
36183620 SanitizerHandler CheckHandler,
36193621 CheckRecoverableKind RecoverKind, bool IsFatal,
3620- llvm::BasicBlock *ContBB, bool NoMerge) {
3622+ llvm::BasicBlock *ContBB, bool NoMerge,
3623+ bool MayReadFromPtrToInt) {
36213624 assert (IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
36223625 std::optional<ApplyDebugLocation> DL;
36233626 if (!CGF.Builder .getCurrentDebugLocation ()) {
@@ -3650,9 +3653,14 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
36503653 if (CGF.CGM .getCodeGenOpts ().OptimizationLevel > 0 && MayReturn) {
36513654 // __ubsan_handle_dynamic_type_cache_miss reads the vtable, which is also
36523655 // accessible by the current module.
3653- if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss)
3654- B.addMemoryAttr (llvm::MemoryEffects::argMemOnly (llvm::ModRefInfo::Ref) |
3655- llvm::MemoryEffects::inaccessibleMemOnly ());
3656+ if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss) {
3657+ llvm::MemoryEffects ME =
3658+ llvm::MemoryEffects::argMemOnly (llvm::ModRefInfo::Ref) |
3659+ llvm::MemoryEffects::inaccessibleMemOnly ();
3660+ if (MayReadFromPtrToInt)
3661+ ME |= llvm::MemoryEffects::readOnly ();
3662+ B.addMemoryAttr (ME);
3663+ }
36563664 // If the handler does not return, it must interact with the environment in
36573665 // an observable way.
36583666 B.addAttribute (llvm::Attribute::MustProgress);
@@ -3753,6 +3761,7 @@ void CodeGenFunction::EmitCheck(
37533761 // representing operand values.
37543762 SmallVector<llvm::Value *, 4 > Args;
37553763 SmallVector<llvm::Type *, 4 > ArgTypes;
3764+ bool MayReadFromPtrToInt = false ;
37563765 if (!CGM.getCodeGenOpts ().SanitizeMinimalRuntime ) {
37573766 Args.reserve (DynamicArgs.size () + 1 );
37583767 ArgTypes.reserve (DynamicArgs.size () + 1 );
@@ -3772,7 +3781,7 @@ void CodeGenFunction::EmitCheck(
37723781 }
37733782
37743783 for (size_t i = 0 , n = DynamicArgs.size (); i != n; ++i) {
3775- Args.push_back (EmitCheckValue (DynamicArgs[i]));
3784+ Args.push_back (EmitCheckValue (DynamicArgs[i], MayReadFromPtrToInt ));
37763785 ArgTypes.push_back (IntPtrTy);
37773786 }
37783787 }
@@ -3784,7 +3793,8 @@ void CodeGenFunction::EmitCheck(
37843793 // Simple case: we need to generate a single handler call, either
37853794 // fatal, or non-fatal.
37863795 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind,
3787- (FatalCond != nullptr ), Cont, NoMerge);
3796+ (FatalCond != nullptr ), Cont, NoMerge,
3797+ MayReadFromPtrToInt);
37883798 } else {
37893799 // Emit two handler calls: first one for set of unrecoverable checks,
37903800 // another one for recoverable.
@@ -3794,10 +3804,10 @@ void CodeGenFunction::EmitCheck(
37943804 Builder.CreateCondBr (FatalCond, NonFatalHandlerBB, FatalHandlerBB);
37953805 EmitBlock (FatalHandlerBB);
37963806 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind, true ,
3797- NonFatalHandlerBB, NoMerge);
3807+ NonFatalHandlerBB, NoMerge, MayReadFromPtrToInt );
37983808 EmitBlock (NonFatalHandlerBB);
37993809 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind, false ,
3800- Cont, NoMerge);
3810+ Cont, NoMerge, MayReadFromPtrToInt );
38013811 }
38023812
38033813 EmitBlock (Cont);
0 commit comments