Merge remote-tracking branch 'origin/swift-3.1-branch' into stable

* origin/swift-3.1-branch:
  Revert "Add -f[no-]strict-return flag that can be used to avoid undefined behaviour"
  Revert "Fix a buildbot failure introduced by r290960."
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 024a0ee..349907f 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -1282,12 +1282,6 @@
 def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">,
   Group<f_Group>, Flags<[CC1Option]>;
 
-def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>,
-  Flags<[CC1Option]>,
-  HelpText<"Always treat control flow paths that fall off the end of a non-void"
-           "function as unreachable">;
-def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>,
-  Flags<[CC1Option]>;
 
 def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index e0bf912..374b0dd 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -242,10 +242,6 @@
 /// Whether to report the hotness of the code region for optimization remarks.
 CODEGENOPT(DiagnosticsWithHotness, 1, 0)
 
-/// Whether we should use the undefined behaviour optimization for control flow
-/// paths that reach the end of a function without executing a required return.
-CODEGENOPT(StrictReturn, 1, 1)
-
 #undef CODEGENOPT
 #undef ENUM_CODEGENOPT
 #undef VALUE_CODEGENOPT
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 146e7f4..7289bf8 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -1008,19 +1008,6 @@
   return ResTy;
 }
 
-static bool
-shouldUseUndefinedBehaviorReturnOptimization(const FunctionDecl *FD,
-                                             const ASTContext &Context) {
-  QualType T = FD->getReturnType();
-  // Avoid the optimization for functions that return a record type with a
-  // trivial destructor or another trivially copyable type.
-  if (const RecordType *RT = T.getCanonicalType()->getAs<RecordType>()) {
-    if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-      return !ClassDecl->hasTrivialDestructor();
-  }
-  return !T.isTriviallyCopyableType(Context);
-}
-
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                                    const CGFunctionInfo &FnInfo) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
@@ -1092,23 +1079,17 @@
   //   function call is used by the caller, the behavior is undefined.
   if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !SawAsmBlock &&
       !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
-    bool ShouldEmitUnreachable =
-        CGM.getCodeGenOpts().StrictReturn ||
-        shouldUseUndefinedBehaviorReturnOptimization(FD, getContext());
     if (SanOpts.has(SanitizerKind::Return)) {
       SanitizerScope SanScope(this);
       llvm::Value *IsFalse = Builder.getFalse();
       EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
                 "missing_return", EmitCheckSourceLocation(FD->getLocation()),
                 None);
-    } else if (ShouldEmitUnreachable) {
-      if (CGM.getCodeGenOpts().OptimizationLevel == 0)
-        EmitTrapCall(llvm::Intrinsic::trap);
+    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
+      EmitTrapCall(llvm::Intrinsic::trap);
     }
-    if (SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
-      Builder.CreateUnreachable();
-      Builder.ClearInsertionPoint();
-    }
+    Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
   }
 
   // Emit the standard function epilogue.
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 65d1f97..f792fc4 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -4252,9 +4252,6 @@
   if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
                    false))
     CmdArgs.push_back("-fstrict-enums");
-  if (!Args.hasFlag(options::OPT_fstrict_return, options::OPT_fno_strict_return,
-                    true))
-    CmdArgs.push_back("-fno-strict-return");
   if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
                    options::OPT_fno_strict_vtable_pointers,
                    false))
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 1977f64..2a1907d 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -589,7 +589,6 @@
   Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
   Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
   Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
-  Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
   Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
   Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
                       Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
diff --git a/test/CodeGenCXX/return.cpp b/test/CodeGenCXX/return.cpp
index 584c292..5c1cfda 100644
--- a/test/CodeGenCXX/return.cpp
+++ b/test/CodeGenCXX/return.cpp
@@ -1,103 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - %s | FileCheck --check-prefixes=CHECK,CHECK-COMMON %s
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -O -o - %s | FileCheck %s --check-prefixes=CHECK-OPT,CHECK-COMMON
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -Wno-return-type -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT,CHECK-COMMON
-// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -fno-strict-return -O -o - %s | FileCheck %s --check-prefixes=CHECK-NOSTRICT-OPT,CHECK-COMMON
+// 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
 
-// CHECK-COMMON-LABEL: @_Z9no_return
+// CHECK:     @_Z9no_return
+// CHECK-OPT: @_Z9no_return
 int no_return() {
   // CHECK:      call void @llvm.trap
   // CHECK-NEXT: unreachable
 
   // CHECK-OPT-NOT: call void @llvm.trap
   // CHECK-OPT:     unreachable
-
-  // -fno-strict-return should not emit trap + unreachable but it should return
-  // an undefined value instead.
-
-  // CHECK-NOSTRICT: alloca
-  // CHECK-NOSTRICT-NEXT: load
-  // CHECK-NOSTRICT-NEXT: ret i32
-  // CHECK-NOSTRICT-NEXT: }
-
-  // CHECK-NOSTRICT-OPT: ret i32 undef
-}
-
-enum Enum {
-  A, B
-};
-
-// CHECK-COMMON-LABEL: @_Z27returnNotViableDontOptimize4Enum
-int returnNotViableDontOptimize(Enum e) {
-  switch (e) {
-  case A: return 1;
-  case B: return 2;
-  }
-  // Undefined behaviour optimization shouldn't be used when -fno-strict-return
-  // is turned on, even if all the enum cases are covered in this function.
-
-  // CHECK-NOSTRICT-NOT: call void @llvm.trap
-  // CHECK-NOSTRICT-NOT: unreachable
-}
-
-struct Trivial {
-  int x;
-};
-
-// CHECK-NOSTRICT-LABEL: @_Z7trivialv
-Trivial trivial() {
-  // This function returns a trivial record so -fno-strict-return should avoid
-  // the undefined behaviour optimization.
-
-  // CHECK-NOSTRICT-NOT: call void @llvm.trap
-  // CHECK-NOSTRICT-NOT: unreachable
-}
-
-struct NonTrivialCopy {
-  NonTrivialCopy(const NonTrivialCopy &);
-};
-
-// CHECK-NOSTRICT-LABEL: @_Z14nonTrivialCopyv
-NonTrivialCopy nonTrivialCopy() {
-  // CHECK-NOSTRICT-NOT: call void @llvm.trap
-  // CHECK-NOSTRICT-NOT: unreachable
-}
-
-struct NonTrivialDefaultConstructor {
-  int x;
-
-  NonTrivialDefaultConstructor() { }
-};
-
-// CHECK-NOSTRICT-LABEL: @_Z28nonTrivialDefaultConstructorv
-NonTrivialDefaultConstructor nonTrivialDefaultConstructor() {
-  // CHECK-NOSTRICT-NOT: call void @llvm.trap
-  // CHECK-NOSTRICT-NOT: unreachable
-}
-
-// Functions that return records with non-trivial destructors should always use
-// the -fstrict-return optimization.
-
-struct NonTrivialDestructor {
-  ~NonTrivialDestructor();
-};
-
-// CHECK-NOSTRICT-LABEL: @_Z20nonTrivialDestructorv
-NonTrivialDestructor nonTrivialDestructor() {
-  // CHECK-NOSTRICT: call void @llvm.trap
-  // CHECK-NOSTRICT-NEXT: unreachable
-}
-
-// The behavior for lambdas should be identical to functions.
-// CHECK-COMMON-LABEL: @_Z10lambdaTestv
-void lambdaTest() {
-  auto lambda1 = []() -> int {
-  };
-  lambda1();
-
-  // CHECK: call void @llvm.trap
-  // CHECK-NEXT: unreachable
-
-  // CHECK-NOSTRICT-NOT: call void @llvm.trap
-  // CHECK-NOSTRICT-NOT: unreachable
 }
diff --git a/test/CodeGenObjCXX/return.mm b/test/CodeGenObjCXX/return.mm
deleted file mode 100644
index 53343e1..0000000
--- a/test/CodeGenObjCXX/return.mm
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -fblocks -triple x86_64-apple-darwin -fstrict-return -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fblocks -triple x86_64-apple-darwin -fstrict-return -O -o - %s | FileCheck %s
-
-@interface I
-@end
-
-@implementation I
-
-- (int)method {
-}
-
-@end
-
-enum Enum {
-  a
-};
-
-int (^block)(Enum) = ^int(Enum e) {
-  switch (e) {
-  case a:
-    return 1;
-  }
-};
-
-// Ensure that both methods and blocks don't use the -fstrict-return undefined
-// behaviour optimization.
-
-// CHECK-NOT: call void @llvm.trap
-// CHECK-NOT: unreachable
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 0a95101..2b49069 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -462,8 +462,3 @@
 // CHECK-WCHAR2: -fshort-wchar
 // CHECK-WCHAR2-NOT: -fno-short-wchar
 // DELIMITERS: {{^ *"}}
-
-// RUN: %clang -### -S -fstrict-return %s 2>&1 | FileCheck -check-prefix=CHECK-STRICT-RETURN %s
-// RUN: %clang -### -S -fno-strict-return %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-RETURN %s
-// CHECK-STRICT-RETURN-NOT: "-fno-strict-return"
-// CHECK-NO-STRICT-RETURN: "-fno-strict-return"