10e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
20e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
30e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
40e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// Basic usage should work.
50e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesint safe_div(int n, int d) {
60e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  int r;
70e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try {
80e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    r = n / d;
90e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(_exception_code() == 0xC0000094) {
100e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    r = 0;
110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return r;
130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
150e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid might_crash();
160e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// Diagnose obvious builtin mis-usage.
180e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid bad_builtin_scope() {
190e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try {
200e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
210e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(1) {
220e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
230e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
240e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
250e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
270e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// Diagnose obvious builtin misusage in a template.
280e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate <void FN()>
290e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid bad_builtin_scope_template() {
300e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try {
310e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    FN();
320e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(1) {
330e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
340e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
350e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
360e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
370e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid instantiate_bad_scope_tmpl() {
380e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  bad_builtin_scope_template<might_crash>();
390e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
400e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
410e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#if __cplusplus < 201103L
420e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// FIXME: Diagnose this case. For now we produce undef in codegen.
430e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate <typename T, T FN()>
440e2c34f92f00628d48968dfea096d36381f494cbStephen HinesT func_template() {
450e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  return FN();
460e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
470e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid inject_builtins() {
480e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  func_template<void *, __exception_info>();
490e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  func_template<unsigned long, __exception_code>();
500e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
510e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#endif
520e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
530e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid use_seh_after_cxx() {
540e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  try { // expected-note {{conflicting 'try' here}}
550e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
560e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } catch (int) {
570e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
580e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
600e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(1) {
610e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
620e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
640e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid use_cxx_after_seh() {
650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try { // expected-note {{conflicting '__try' here}}
660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
670e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(1) {
680e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
710e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } catch (int) {
720e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
730e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
740e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
750e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#if __cplusplus >= 201103L
760e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid use_seh_in_lambda() {
770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  ([]() {
780e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    __try {
790e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      might_crash();
800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    } __except(1) {
810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    }
820e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  })();
830e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  try {
840e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
850e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } catch (int) {
860e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
870e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
880e2c34f92f00628d48968dfea096d36381f494cbStephen Hines#endif
890e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
900e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid use_seh_in_block() {
910e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  void (^b)() = ^{
920e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
930e2c34f92f00628d48968dfea096d36381f494cbStephen Hines      might_crash();
940e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    } __except(1) {
950e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    }
960e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  };
970e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  try {
980e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    b();
990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } catch (int) {
1000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
1010e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
1020e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1030e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid (^use_seh_in_global_block)() = ^{
1040e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
1050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
1060e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } __except(1) {
1070e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
1080e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
1090e2c34f92f00628d48968dfea096d36381f494cbStephen Hines
1100e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid (^use_cxx_in_global_block)() = ^{
1110e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  try {
1120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    might_crash();
1130e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  } catch(int) {
1140e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  }
1150e2c34f92f00628d48968dfea096d36381f494cbStephen Hines};
116