From 1efdec2c252d1f64092fcf2d829b60171623cd74 Mon Sep 17 00:00:00 2001
From: Sjoerd Meijer <sjoerd.meijer@arm.com>
Date: Mon, 17 Aug 2015 11:38:35 +0100
Subject: [PATCH] Always trap for missing return statements, except when
 optimizing for size.

---
 lib/CodeGen/CodeGenFunction.cpp | 7 ++++++-
 test/CodeGenCXX/return.cpp      | 7 ++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 9bf4161..a663f16 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -926,7 +926,12 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
       EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
                 "missing_return", EmitCheckSourceLocation(FD->getLocation()),
                 None);
-    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+    } else if (!CGM.getCodeGenOpts().OptimizeSize) {
+      // A missing return statement provides opportunities for optimizing away
+      // unreachable control flow, i.e it is a code-size optimization opportunity. 
+      // However, not returning from a function is potentially unsafe and also not 
+      // so user-friendly. Therefore, we trap for all optimizations levels, except 
+      // when optimizing for size.
       EmitTrapCall(llvm::Intrinsic::trap);
     }
     Builder.CreateUnreachable();
diff --git a/test/CodeGenCXX/return.cpp b/test/CodeGenCXX/return.cpp
index 5c1cfda..b02b2a8 100644
--- a/test/CodeGenCXX/return.cpp
+++ b/test/CodeGenCXX/return.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -O -o - %s | FileCheck %s --check-prefix=CHECK-OPT
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -O -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -Oz -o - %s | FileCheck %s --check-prefix=CHECK-OPT-SIZE
 
 // CHECK:     @_Z9no_return
 // CHECK-OPT: @_Z9no_return
@@ -7,6 +8,6 @@ int no_return() {
   // CHECK:      call void @llvm.trap
   // CHECK-NEXT: unreachable
 
-  // CHECK-OPT-NOT: call void @llvm.trap
-  // CHECK-OPT:     unreachable
+  // CHECK-OPT-SIZE-NOT: call void @llvm.trap
+  // CHECK-OPT-SIZE:     unreachable
 }
-- 
1.9.1

