From 65f0785fff0e45f8cd1b9e90328597197beef899 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Thu, 6 Feb 2020 10:17:36 -0800 Subject: [PATCH] [ubsan] Omit return value check when return block is unreachable If the return block is unreachable, clang removes it in CodeGenFunction::FinishFunction(). This removal can leave dangling references to values defined in the return block if the return block has successors, which it /would/ if UBSan's return value check is emitted. In this case, as the UBSan check wouldn't be reachable, it's better to simply not emit it. rdar://59196131 --- clang/lib/CodeGen/CGCall.cpp | 5 +++++ .../CodeGenObjC/ubsan-nullability-return-unreachable.m | 14 ++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index cdd3ca4..b55d585 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3035,6 +3035,11 @@ void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) { if (!CurCodeDecl) return; + // If the return block isn't reachable, neither is this check, so don't emit + // it. + if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) + return; + ReturnsNonNullAttr *RetNNAttr = nullptr; if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute)) RetNNAttr = CurCodeDecl->getAttr(); diff --git a/clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m b/clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m new file mode 100644 index 0000000..eabc33c --- /dev/null +++ b/clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsanitize=nullability-return -emit-llvm %s -o - -triple x86_64-apple-macosx10.10.0 -Wno-objc-root-class | FileCheck %s + +// CHECK-LABEL: define internal i8* @"\01-[I init]" +// CHECK: unreachable +// CHECK-NEXT: } + +#pragma clang assume_nonnull begin +@interface I +- (instancetype)init __attribute__((unavailable)); +@end +@implementation I +- (instancetype)init __attribute__((unavailable)) { __builtin_unreachable(); } +@end +#pragma clang assume_nonnull end -- 2.7.4