summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/scope-check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/scope-check.cpp')
-rw-r--r--test/SemaCXX/scope-check.cpp191
1 files changed, 189 insertions, 2 deletions
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index ac70099..9e00332 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
+// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions %s -Wno-unreachable-code
+// RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions -std=gnu++11 %s -Wno-unreachable-code
namespace testInvalid {
Invalid inv; // expected-error {{unknown type name}}
@@ -441,3 +441,190 @@ namespace test_recovery {
}
}
}
+
+namespace seh {
+
+// Jumping into SEH try blocks is not permitted.
+
+void jump_into_except() {
+ goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
+ __try { // expected-note {{jump bypasses initialization of __try block}}
+ into_try_except_try:
+ ;
+ } __except(0) {
+ }
+
+ goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}}
+ __try {
+ } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
+ into_try_except_except:
+ ;
+ }
+}
+
+void jump_into_finally() {
+ goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
+ __try { // expected-note {{jump bypasses initialization of __try block}}
+ into_try_except_try:
+ ;
+ } __finally {
+ }
+
+ goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}}
+ __try {
+ } __finally { // expected-note {{jump bypasses initialization of __finally block}}
+ into_try_except_finally:
+ ;
+ }
+}
+
+// Jumping out of SEH try blocks ok in general. (Jumping out of a __finally
+// has undefined behavior.)
+
+void jump_out_of_except() {
+ __try {
+ goto out_of_except_try;
+ } __except(0) {
+ }
+out_of_except_try:
+ ;
+
+ __try {
+ } __except(0) {
+ goto out_of_except_except;
+ }
+out_of_except_except:
+ ;
+}
+
+void jump_out_of_finally() {
+ __try {
+ goto out_of_finally_try;
+ } __finally {
+ }
+out_of_finally_try:
+ ;
+
+ __try {
+ } __finally {
+ goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
+ }
+
+ __try {
+ } __finally {
+ goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
+ }
+out_of_finally_finally:
+ ;
+}
+
+// Jumping between protected scope and handler is not permitted.
+
+void jump_try_except() {
+ __try {
+ goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}}
+ } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
+ from_try_to_except:
+ ;
+ }
+
+ __try { // expected-note {{jump bypasses initialization of __try block}}
+ from_except_to_try:
+ ;
+ } __except(0) {
+ goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}}
+ }
+}
+
+void jump_try_finally() {
+ __try {
+ goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}}
+ } __finally { // expected-note {{jump bypasses initialization of __finally block}}
+ from_try_to_finally:
+ ;
+ }
+
+ __try { // expected-note {{jump bypasses initialization of __try block}}
+ from_finally_to_try:
+ ;
+ } __finally {
+ goto from_finally_to_try; // expected-error {{cannot jump from this goto statement to its label}} expected-warning {{jump out of __finally block has undefined behavior}}
+ }
+}
+
+void nested() {
+ // These are not permitted.
+ __try {
+ __try {
+ } __finally {
+ goto outer_except; // expected-error {{cannot jump from this goto statement to its label}}
+ }
+ } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}}
+ outer_except:
+ ;
+ }
+
+ __try {
+ __try{
+ } __except(0) {
+ goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}}
+ }
+ } __finally { // expected-note {{jump bypasses initialization of __finally bloc}}
+ outer_finally:
+ ;
+ }
+
+ // These are permitted.
+ __try {
+ __try {
+ } __finally {
+ goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}}
+ }
+ } __except(0) {
+ }
+after_outer_except:
+ ;
+
+ __try {
+ __try{
+ } __except(0) {
+ goto after_outer_finally;
+ }
+ } __finally {
+ }
+after_outer_finally:
+ ;
+}
+
+// This section is academic, as MSVC doesn't support indirect gotos.
+
+void indirect_jumps(void **ip) {
+ static void *ips[] = { &&l };
+
+ __try { // expected-note {{jump exits __try block}}
+ // FIXME: Should this be allowed? Jumping out of the guarded section of a
+ // __try/__except doesn't require unwinding.
+ goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
+ } __except(0) {
+ }
+
+ __try {
+ } __except(0) { // expected-note {{jump exits __except block}}
+ // FIXME: What about here?
+ goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
+ }
+
+ __try { // expected-note {{jump exits __try block}}
+ goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
+ } __finally {
+ }
+
+ __try {
+ } __finally { // expected-note {{jump exits __finally block}}
+ goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
+ }
+l: // expected-note 4 {{possible target of indirect goto statement}}
+ ;
+}
+
+} // namespace seh
OpenPOWER on IntegriCloud