Skip to content

Commit 0bf78cc

Browse files
committed
[Clang][CodeGen] Add memory(read) if the check value is passed by ref
1 parent c23336e commit 0bf78cc

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
@@ -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);

clang/lib/CodeGen/CodeGenFunction.h

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

52255225
/// Convert a value into a format suitable for passing to a runtime
52265226
/// sanitizer handler.
5227-
llvm::Value *EmitCheckValue(llvm::Value *V);
5227+
/// If the check value is a pointer or passed by reference, set \p
5228+
/// MayReadFromPtrToInt to true.
5229+
llvm::Value *EmitCheckValue(llvm::Value *V, bool &MayReadFromPtrToInt);
52285230

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