summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/exceptions-seh.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/exceptions-seh.cpp')
-rw-r--r--test/SemaCXX/exceptions-seh.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/test/SemaCXX/exceptions-seh.cpp b/test/SemaCXX/exceptions-seh.cpp
new file mode 100644
index 0000000..7375ec9
--- /dev/null
+++ b/test/SemaCXX/exceptions-seh.cpp
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
+// RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s
+
+// Basic usage should work.
+int safe_div(int n, int d) {
+ int r;
+ __try {
+ r = n / d;
+ } __except(_exception_code() == 0xC0000094) {
+ r = 0;
+ }
+ return r;
+}
+
+void might_crash();
+
+// Diagnose obvious builtin mis-usage.
+void bad_builtin_scope() {
+ __try {
+ might_crash();
+ } __except(1) {
+ }
+ _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
+ _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
+}
+
+// Diagnose obvious builtin misusage in a template.
+template <void FN()>
+void bad_builtin_scope_template() {
+ __try {
+ FN();
+ } __except(1) {
+ }
+ _exception_code(); // expected-error {{'_exception_code' only allowed in __except block or filter expression}}
+ _exception_info(); // expected-error {{'_exception_info' only allowed in __except filter expression}}
+}
+void instantiate_bad_scope_tmpl() {
+ bad_builtin_scope_template<might_crash>();
+}
+
+#if __cplusplus < 201103L
+// FIXME: Diagnose this case. For now we produce undef in codegen.
+template <typename T, T FN()>
+T func_template() {
+ return FN();
+}
+void inject_builtins() {
+ func_template<void *, __exception_info>();
+ func_template<unsigned long, __exception_code>();
+}
+#endif
+
+void use_seh_after_cxx() {
+ try { // expected-note {{conflicting 'try' here}}
+ might_crash();
+ } catch (int) {
+ }
+ __try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
+ might_crash();
+ } __except(1) {
+ }
+}
+
+void use_cxx_after_seh() {
+ __try { // expected-note {{conflicting '__try' here}}
+ might_crash();
+ } __except(1) {
+ }
+ try { // expected-error {{cannot use C++ 'try' in the same function as SEH '__try'}}
+ might_crash();
+ } catch (int) {
+ }
+}
+
+#if __cplusplus >= 201103L
+void use_seh_in_lambda() {
+ ([]() {
+ __try {
+ might_crash();
+ } __except(1) {
+ }
+ })();
+ try {
+ might_crash();
+ } catch (int) {
+ }
+}
+#endif
+
+void use_seh_in_block() {
+ void (^b)() = ^{
+ __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
+ might_crash();
+ } __except(1) {
+ }
+ };
+ try {
+ b();
+ } catch (int) {
+ }
+}
+
+void (^use_seh_in_global_block)() = ^{
+ __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}
+ might_crash();
+ } __except(1) {
+ }
+};
+
+void (^use_cxx_in_global_block)() = ^{
+ try {
+ might_crash();
+ } catch(int) {
+ }
+};
OpenPOWER on IntegriCloud