Skip to content

Commit 9aba004

Browse files
committed
[Clang][CodeGen] Add memory(read) if the check value is passed by ref
1 parent b6f0d59 commit 9aba004

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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);

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5244,7 +5244,9 @@ class CodeGenFunction : public CodeGenTypeCache {
52445244

52455245
/// Convert a value into a format suitable for passing to a runtime
52465246
/// sanitizer handler.
5247-
llvm::Value *EmitCheckValue(llvm::Value *V);
5247+
/// If the check value is a pointer or passed by reference, set \p
5248+
/// MayReadFromPtrToInt to true.
5249+
llvm::Value *EmitCheckValue(llvm::Value *V, bool &MayReadFromPtrToInt);
52485250

52495251
/// Emit a description of a source location in a format suitable for
52505252
/// passing to a runtime sanitizer handler.

clang/test/CodeGen/AArch64/ubsan-handler-pass-by-ref.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
// RECOVER-SAME: ) local_unnamed_addr #[[ATTR0:[0-9]+]] {
99
// RECOVER-NEXT: [[ENTRY:.*:]]
1010
// RECOVER-NEXT: [[TMP:%.*]] = alloca i64, align 8
11-
// RECOVER-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[TMP]] to i32, !nosanitize [[META3:![0-9]+]]
11+
// RECOVER-NEXT: store i64 -9223372036854775808, ptr [[TMP]], align 8, !nosanitize [[META3:![0-9]+]]
12+
// RECOVER-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[TMP]] to i32, !nosanitize [[META3]]
1213
// RECOVER-NEXT: call void @__ubsan_handle_negate_overflow(ptr nonnull @[[GLOB1:[0-9]+]], i32 [[TMP0]]) #[[ATTR2:[0-9]+]], !nosanitize [[META3]]
1314
// RECOVER-NEXT: ret i32 0
1415
//

0 commit comments

Comments
 (0)