text: // RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
  // RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
  
  void abort(void) __attribute__((noreturn));
  void might_crash(void);
  void cleanup(void);
  int check_condition(void);
  void basic_finally(void) {
    __try {
      might_crash();
    } __finally {
      cleanup();
    }
  }
  
  // CHECK-LABEL: define void @basic_finally()
  // CHECK: invoke void @might_crash()
  // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
  //
  // CHECK: [[invoke_cont]]
  // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
  // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
  // CHECK-NEXT: ret void
  //
  // CHECK: [[lpad]]
  // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
  // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
  // CHECK: call void @"\01?fin$0@0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
  // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
  
  // CHECK: define internal void @"\01?fin$0@0@basic_finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs:#[0-9]+]]
  // CHECK: call void @cleanup()
  
  // Mostly check that we don't double emit 'r' which would crash.
  void decl_in_finally(void) {
    __try {
      might_crash();
    } __finally {
      int r;
    }
  }
  
  // Ditto, don't crash double emitting 'l'.
  void label_in_finally(void) {
    __try {
      might_crash();
    } __finally {
  l:
      cleanup();
      if (check_condition())
        goto l;
    }
  }
  
  // CHECK-LABEL: define void @label_in_finally()
  // CHECK: invoke void @might_crash()
  // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
  //
  // CHECK: [[invoke_cont]]
  // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
  // CHECK: call void @"\01?fin$0@0@label_in_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
  // CHECK: ret void
  
  // CHECK: define internal void @"\01?fin$0@0@label_in_finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: br label %[[l:[^ ]*]]
  //
  // CHECK: [[l]]
  // CHECK: call void @cleanup()
  // CHECK: call i32 @check_condition()
  // CHECK: br i1 {{.*}}, label
  // CHECK: br label %[[l]]
  
  int crashed;
  void use_abnormal_termination(void) {
    __try {
      might_crash();
    } __finally {
      crashed = __abnormal_termination();
    }
  }
  
  // CHECK-LABEL: define void @use_abnormal_termination()
  // CHECK: invoke void @might_crash()
  // CHECK:     to label %[[invoke_cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
  //
  // CHECK: [[invoke_cont]]
  // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
  // CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
  // CHECK: ret void
  //
  // CHECK: [[lpad]]
  // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
  // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
  // CHECK: call void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
  // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
  
  // CHECK: define internal void @"\01?fin$0@0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32
  // CHECK: store i32 %[[abnormal_zext]], i32* @crashed
  // CHECK-NEXT: ret void
  
  void noreturn_noop_finally() {
    __try {
      __noop();
    } __finally {
      abort();
    }
  }
  
  // CHECK-LABEL: define void @noreturn_noop_finally()
  // CHECK: call void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
  // CHECK: ret void
  
  // CHECK: define internal void @"\01?fin$0@0@noreturn_noop_finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: call void @abort()
  // CHECK: unreachable
  
  void noreturn_finally() {
    __try {
      might_crash();
    } __finally {
      abort();
    }
  }
  
  // CHECK-LABEL: define void @noreturn_finally()
  // CHECK: invoke void @might_crash()
  // CHECK:     to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
  //
  // CHECK: [[cont]]
  // CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
  // CHECK: ret void
  //
  // CHECK: [[lpad]]
  // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
  // CHECK: call void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
  // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
  
  // CHECK: define internal void @"\01?fin$0@0@noreturn_finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: call void @abort()
  // CHECK: unreachable
  
  int finally_with_return() {
    __try {
      return 42;
    } __finally {
    }
  }
  // CHECK-LABEL: define i32 @finally_with_return()
  // CHECK: call void @"\01?fin$0@0@finally_with_return@@"({{.*}})
  // CHECK-NEXT: ret i32 42
  
  // CHECK: define internal void @"\01?fin$0@0@finally_with_return@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK-NOT: br i1
  // CHECK-NOT: br label
  // CHECK: ret void
  
  int nested___finally___finally() {
    __try {
      __try {
      } __finally {
        return 1;
      }
    } __finally {
      // Intentionally no return here.
    }
    return 0;
  }
  
  // CHECK-LABEL: define i32 @nested___finally___finally
  // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
  // CHECK:          to label %[[outercont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
  //
  // CHECK: [[outercont]]
  // CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
  // CHECK-NEXT: ret i32 0
  //
  // CHECK: [[lpad]]
  // CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
  // CHECK: call void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
  // CHECK-NEXT: cleanupret from %[[pad]] unwind to caller
  
  // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: ret void
  
  // CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: unreachable
  
  // FIXME: Our behavior seems suspiciously different.
  
  int nested___finally___finally_with_eh_edge() {
    __try {
      __try {
        might_crash();
      } __finally {
        return 899;
      }
    } __finally {
      // Intentionally no return here.
    }
    return 912;
  }
  // CHECK-LABEL: define i32 @nested___finally___finally_with_eh_edge
  // CHECK: invoke void @might_crash()
  // CHECK-NEXT: to label %[[invokecont:[^ ]*]] unwind label %[[lpad1:[^ ]*]]
  //
  // [[invokecont]]
  // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-NEXT:       to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
  //
  // CHECK: [[outercont]]
  // CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-NEXT: ret i32 912
  //
  // CHECK: [[lpad1]]
  // CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad
  // CHECK: invoke void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-NEXT:    label %[[innercleanupretbb:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
  //
  // CHECK: [[innercleanupretbb]]
  // CHECK-NEXT: cleanupret from %[[innerpad]] unwind label %[[lpad2]]
  //
  // CHECK: [[lpad2]]
  // CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad
  // CHECK: call void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-NEXT: cleanupret from %[[outerpad]] unwind to caller
  
  // CHECK-LABEL: define internal void @"\01?fin$0@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: ret void
  
  // CHECK-LABEL: define internal void @"\01?fin$1@0@nested___finally___finally_with_eh_edge@@"({{.*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: unreachable
  
  void finally_within_finally() {
    __try {
      might_crash();
    } __finally {
      __try {
        might_crash();
      } __finally {
      }
    }
  }
  
  // CHECK-LABEL: define void @finally_within_finally(
  // CHECK: invoke void @might_crash(
  
  // CHECK: call void @"\01?fin$0@0@finally_within_finally@@"(
  // CHECK: call void @"\01?fin$0@0@finally_within_finally@@"({{.*}}) [ "funclet"(
  
  // CHECK-LABEL: define internal void @"\01?fin$0@0@finally_within_finally@@"({{[^)]*}})
  // CHECK-SAME: [[finally_attrs]]
  // CHECK: invoke void @might_crash(
  
  // CHECK: call void @"\01?fin$1@0@finally_within_finally@@"(
  // CHECK: call void @"\01?fin$1@0@finally_within_finally@@"({{.*}}) [ "funclet"(
  
  // CHECK-LABEL: define internal void @"\01?fin$1@0@finally_within_finally@@"({{[^)]*}})
  // CHECK-SAME: [[finally_attrs]]
  
  // Look for the absence of noinline. Enum attributes come first, so check that
  // a string attribute is the first to verify that no enum attributes are
  // present.
  // CHECK: attributes [[finally_attrs]] = { "{{.*}}" }
  