Skip to content

Commit f89b114

Browse files
committed
[Clang][CodeGen] Add memory(read) if the check value is passed by ref
1 parent 0777a3e commit f89b114

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,7 +1972,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
19721972
SanitizerKind::SanitizerOrdinal Kind =
19731973
NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
19741974
EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
1975-
StaticArgs, EmitCheckValue(Value));
1975+
StaticArgs, Value);
19761976
return true;
19771977
}
19781978

@@ -3462,7 +3462,8 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
34623462
return GV;
34633463
}
34643464

3465-
llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
3465+
llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V,
3466+
bool &MayReadFromPtrToInt) {
34663467
llvm::Type *TargetTy = IntPtrTy;
34673468

34683469
if (V->getType() == TargetTy)
@@ -3488,6 +3489,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
34883489
Builder.CreateStore(V, Ptr);
34893490
V = Ptr.getPointer();
34903491
}
3492+
MayReadFromPtrToInt = true;
34913493
return Builder.CreatePtrToInt(V, TargetTy);
34923494
}
34933495

@@ -3593,7 +3595,8 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
35933595
ArrayRef<llvm::Value *> FnArgs,
35943596
SanitizerHandler CheckHandler,
35953597
CheckRecoverableKind RecoverKind, bool IsFatal,
3596-
llvm::BasicBlock *ContBB, bool NoMerge) {
3598+
llvm::BasicBlock *ContBB, bool NoMerge,
3599+
bool MayReadFromPtrToInt) {
35973600
assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
35983601
std::optional<ApplyDebugLocation> DL;
35993602
if (!CGF.Builder.getCurrentDebugLocation()) {
@@ -3626,9 +3629,14 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF,
36263629
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 && MayReturn) {
36273630
// __ubsan_handle_dynamic_type_cache_miss reads the vtable, which is also
36283631
// accessible by the current module.
3629-
if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss)
3630-
B.addMemoryAttr(llvm::MemoryEffects::argMemOnly(llvm::ModRefInfo::Ref) |
3631-
llvm::MemoryEffects::inaccessibleMemOnly());
3632+
if (CheckHandler != SanitizerHandler::DynamicTypeCacheMiss) {
3633+
llvm::MemoryEffects ME =
3634+
llvm::MemoryEffects::argMemOnly(llvm::ModRefInfo::Ref) |
3635+
llvm::MemoryEffects::inaccessibleMemOnly();
3636+
if (MayReadFromPtrToInt)
3637+
ME |= llvm::MemoryEffects::readOnly();
3638+
B.addMemoryAttr(ME);
3639+
}
36323640
// If the handler does not return, it must interact with the environment in
36333641
// an observable way.
36343642
B.addAttribute(llvm::Attribute::MustProgress);
@@ -3729,6 +3737,7 @@ void CodeGenFunction::EmitCheck(
37293737
// representing operand values.
37303738
SmallVector<llvm::Value *, 4> Args;
37313739
SmallVector<llvm::Type *, 4> ArgTypes;
3740+
bool MayReadFromPtrToInt = false;
37323741
if (!CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
37333742
Args.reserve(DynamicArgs.size() + 1);
37343743
ArgTypes.reserve(DynamicArgs.size() + 1);
@@ -3748,7 +3757,7 @@ void CodeGenFunction::EmitCheck(
37483757
}
37493758

37503759
for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
3751-
Args.push_back(EmitCheckValue(DynamicArgs[i]));
3760+
Args.push_back(EmitCheckValue(DynamicArgs[i], MayReadFromPtrToInt));
37523761
ArgTypes.push_back(IntPtrTy);
37533762
}
37543763
}
@@ -3760,7 +3769,8 @@ void CodeGenFunction::EmitCheck(
37603769
// Simple case: we need to generate a single handler call, either
37613770
// fatal, or non-fatal.
37623771
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind,
3763-
(FatalCond != nullptr), Cont, NoMerge);
3772+
(FatalCond != nullptr), Cont, NoMerge,
3773+
MayReadFromPtrToInt);
37643774
} else {
37653775
// Emit two handler calls: first one for set of unrecoverable checks,
37663776
// another one for recoverable.
@@ -3770,10 +3780,10 @@ void CodeGenFunction::EmitCheck(
37703780
Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
37713781
EmitBlock(FatalHandlerBB);
37723782
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, true,
3773-
NonFatalHandlerBB, NoMerge);
3783+
NonFatalHandlerBB, NoMerge, MayReadFromPtrToInt);
37743784
EmitBlock(NonFatalHandlerBB);
37753785
emitCheckHandlerCall(*this, FnType, Args, CheckHandler, RecoverKind, false,
3776-
Cont, NoMerge);
3786+
Cont, NoMerge, MayReadFromPtrToInt);
37773787
}
37783788

37793789
EmitBlock(Cont);

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,9 +3197,7 @@ void CodeGenFunction::emitAlignmentAssumptionCheck(
31973197
llvm::Constant *StaticData[] = {EmitCheckSourceLocation(Loc),
31983198
EmitCheckSourceLocation(SecondaryLoc),
31993199
EmitCheckTypeDescriptor(Ty)};
3200-
llvm::Value *DynamicData[] = {EmitCheckValue(Ptr),
3201-
EmitCheckValue(Alignment),
3202-
EmitCheckValue(OffsetValue)};
3200+
llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
32033201
EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},
32043202
SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
32053203
}

clang/lib/CodeGen/CodeGenFunction.h

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

52205220
/// Convert a value into a format suitable for passing to a runtime
52215221
/// sanitizer handler.
5222-
llvm::Value *EmitCheckValue(llvm::Value *V);
5222+
/// If the check value is a pointer or passed by reference, set \p
5223+
/// MayReadFromPtrToInt to true.
5224+
llvm::Value *EmitCheckValue(llvm::Value *V, bool &MayReadFromPtrToInt);
52235225

52245226
/// Emit a description of a source location in a format suitable for
52255227
/// 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)