[ubsan] Omit return value check when return block is unreachable
authorVedant Kumar <vsk@apple.com>
Thu, 6 Feb 2020 18:17:36 +0000 (10:17 -0800)
committerVedant Kumar <vsk@apple.com>
Thu, 6 Feb 2020 18:24:03 +0000 (10:24 -0800)
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
clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m [new file with mode: 0644]

index cdd3ca4..b55d585 100644 (file)
@@ -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<ReturnsNonNullAttr>();
diff --git a/clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m b/clang/test/CodeGenObjC/ubsan-nullability-return-unreachable.m
new file mode 100644 (file)
index 0000000..eabc33c
--- /dev/null
@@ -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