@@ -3456,7 +3456,8 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
34563456 return GV;
34573457}
34583458
3459- llvm::Value *CodeGenFunction::EmitCheckValue (llvm::Value *V) {
3459+ llvm::Value *CodeGenFunction::EmitCheckValue (llvm::Value *V,
3460+ bool &MayReadFromPtrToInt) {
34603461 llvm::Type *TargetTy = IntPtrTy;
34613462
34623463 if (V->getType () == TargetTy)
@@ -3482,6 +3483,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
34823483 Builder.CreateStore (V, Ptr);
34833484 V = Ptr.getPointer ();
34843485 }
3486+ MayReadFromPtrToInt = true ;
34853487 return Builder.CreatePtrToInt (V, TargetTy);
34863488}
34873489
@@ -3587,7 +3589,8 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
35873589 ArrayRef<llvm::Value *> FnArgs,
35883590 SanitizerHandler CheckHandler,
35893591 CheckRecoverableKind RecoverKind, bool IsFatal,
3590- llvm::BasicBlock *ContBB, bool NoMerge) {
3592+ llvm::BasicBlock *ContBB, bool NoMerge,
3593+ bool MayReadFromPtrToInt) {
35913594 assert (IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
35923595 std::optional<ApplyDebugLocation> DL;
35933596 if (!CGF.Builder .getCurrentDebugLocation ()) {
@@ -3620,9 +3623,14 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
36203623 if (CGF.CGM .getCodeGenOpts ().OptimizationLevel > 0 && MayReturn) {
36213624 // __ubsan_handle_dynamic_type_cache_miss reads the vtable, which is also
36223625 // accessible by the current module.
3623- if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss)
3624- B.addMemoryAttr (llvm::MemoryEffects::argMemOnly (llvm::ModRefInfo::Ref) |
3625- llvm::MemoryEffects::inaccessibleMemOnly ());
3626+ if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss) {
3627+ llvm::MemoryEffects ME =
3628+ llvm::MemoryEffects::argMemOnly (llvm::ModRefInfo::Ref) |
3629+ llvm::MemoryEffects::inaccessibleMemOnly ();
3630+ if (MayReadFromPtrToInt)
3631+ ME |= llvm::MemoryEffects::readOnly ();
3632+ B.addMemoryAttr (ME);
3633+ }
36263634 // If the handler does not return, it must interact with the environment in
36273635 // an observable way.
36283636 B.addAttribute (llvm::Attribute::MustProgress);
@@ -3723,6 +3731,7 @@ void CodeGenFunction::EmitCheck(
37233731 // representing operand values.
37243732 SmallVector<llvm::Value *, 4 > Args;
37253733 SmallVector<llvm::Type *, 4 > ArgTypes;
3734+ bool MayReadFromPtrToInt = false ;
37263735 if (!CGM.getCodeGenOpts ().SanitizeMinimalRuntime ) {
37273736 Args.reserve (DynamicArgs.size () + 1 );
37283737 ArgTypes.reserve (DynamicArgs.size () + 1 );
@@ -3742,7 +3751,7 @@ void CodeGenFunction::EmitCheck(
37423751 }
37433752
37443753 for (size_t i = 0 , n = DynamicArgs.size (); i != n; ++i) {
3745- Args.push_back (EmitCheckValue (DynamicArgs[i]));
3754+ Args.push_back (EmitCheckValue (DynamicArgs[i], MayReadFromPtrToInt ));
37463755 ArgTypes.push_back (IntPtrTy);
37473756 }
37483757 }
@@ -3754,7 +3763,8 @@ void CodeGenFunction::EmitCheck(
37543763 // Simple case: we need to generate a single handler call, either
37553764 // fatal, or non-fatal.
37563765 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind,
3757- (FatalCond != nullptr ), Cont, NoMerge);
3766+ (FatalCond != nullptr ), Cont, NoMerge,
3767+ MayReadFromPtrToInt);
37583768 } else {
37593769 // Emit two handler calls: first one for set of unrecoverable checks,
37603770 // another one for recoverable.
@@ -3764,10 +3774,10 @@ void CodeGenFunction::EmitCheck(
37643774 Builder.CreateCondBr (FatalCond, NonFatalHandlerBB, FatalHandlerBB);
37653775 EmitBlock (FatalHandlerBB);
37663776 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind, true ,
3767- NonFatalHandlerBB, NoMerge);
3777+ NonFatalHandlerBB, NoMerge, MayReadFromPtrToInt );
37683778 EmitBlock (NonFatalHandlerBB);
37693779 emitCheckHandlerCall (*this , FnType, Args, CheckHandler, RecoverKind, false ,
3770- Cont, NoMerge);
3780+ Cont, NoMerge, MayReadFromPtrToInt );
37713781 }
37723782
37733783 EmitBlock (Cont);
0 commit comments