[DebugInfo] Avoid applying a misleading cleanup loc in case blocks

Switch cases without a trailing curly brace have ambiguous cleanup
locations. Here's what the current stepping behavior looks like:

  switch x {
    case ...:
      if true { foo() } // Step
      else    { bar() } // Step
  }

The second step can be misleading, because users might think that the
else branch is taken.

rdar://35628620
(cherry picked from commit b27ed065b6bb67c27a4e5f8e8863ee7c12f32065)
diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp
index 6c27178..664eb3f 100644
--- a/lib/SILGen/SILGenPattern.cpp
+++ b/lib/SILGen/SILGenPattern.cpp
@@ -2315,7 +2315,13 @@
 
   // Implicitly break out of the pattern match statement.
   if (SGF.B.hasValidInsertionPoint()) {
-    SGF.emitBreakOutOf(CleanupLocation(caseBlock), PatternMatchStmt);
+    // Case blocks without trailing braces have ambiguous cleanup locations.
+    SILLocation cleanupLoc = getCompilerGeneratedLocation();
+    if (auto *braces = dyn_cast<BraceStmt>(caseBlock->getBody()))
+      if (braces->getNumElements() == 1 &&
+          dyn_cast_or_null<DoStmt>(braces->getElement(0).dyn_cast<Stmt *>()))
+        cleanupLoc = CleanupLocation(caseBlock);
+    SGF.emitBreakOutOf(cleanupLoc, PatternMatchStmt);
   }
 }
 
diff --git a/test/DebugInfo/patternmatching.swift b/test/DebugInfo/patternmatching.swift
index b98d31a..144a66f 100644
--- a/test/DebugInfo/patternmatching.swift
+++ b/test/DebugInfo/patternmatching.swift
@@ -23,7 +23,7 @@
       markUsed(x)
       // SIL-CHECK:  dealloc_stack{{.*}}line:[[@LINE-1]]:17:cleanup
       // Verify that the branch has a location >= the cleanup.
-      // SIL-CHECK-NEXT:  br{{.*}}line:[[@LINE-3]]:17:cleanup
+      // SIL-CHECK-NEXT:  br{{.*}}no_loc
       // CHECK-SCOPES: call void @llvm.dbg
       // CHECK-SCOPES: call void @llvm.dbg
       // CHECK-SCOPES: call void @llvm.dbg
@@ -56,5 +56,16 @@
       // CHECK-SCOPES-SAME:                     scope: ![[SCOPE3]])
       markUsed(x)
     }
+
+switch p {
+    case (let x, let y) where x == 0:
+      if y == 0 { markUsed(x) }
+      else      { markUsed(y) } // SIL-CHECK-NOT: br{{.*}}line:[[@LINE]]:31:cleanup
+    case (let x, let y): do {
+      if y == 0 { markUsed(x) }
+      else      { markUsed(y) }
+    } // SIL-CHECK: br{{.*}}line:[[@LINE]]:5:cleanup
+}
+
 // CHECK: !DILocation(line: [[@LINE+1]],
 }