summaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/scope-check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/scope-check.cpp')
-rw-r--r--clang/test/SemaCXX/scope-check.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/scope-check.cpp b/clang/test/SemaCXX/scope-check.cpp
new file mode 100644
index 0000000..b659de0
--- /dev/null
+++ b/clang/test/SemaCXX/scope-check.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code
+
+namespace test0 {
+ struct D { ~D(); };
+
+ int f(bool b) {
+ if (b) {
+ D d;
+ goto end;
+ }
+
+ end:
+ return 1;
+ }
+}
+
+namespace test1 {
+ struct C { C(); };
+
+ int f(bool b) {
+ if (b)
+ goto foo; // expected-error {{goto into protected scope}}
+ C c; // expected-note {{jump bypasses variable initialization}}
+ foo:
+ return 1;
+ }
+}
+
+namespace test2 {
+ struct C { C(); };
+
+ int f(void **ip) {
+ static void *ips[] = { &&lbl1, &&lbl2 };
+
+ C c;
+ goto *ip;
+ lbl1:
+ return 0;
+ lbl2:
+ return 1;
+ }
+}
+
+namespace test3 {
+ struct C { C(); };
+
+ int f(void **ip) {
+ static void *ips[] = { &&lbl1, &&lbl2 };
+
+ goto *ip;
+ lbl1: {
+ C c;
+ return 0;
+ }
+ lbl2:
+ return 1;
+ }
+}
+
+namespace test4 {
+ struct C { C(); };
+ struct D { ~D(); };
+
+ int f(void **ip) {
+ static void *ips[] = { &&lbl1, &&lbl2 };
+
+ C c0;
+
+ goto *ip; // expected-error {{indirect goto might cross protected scopes}}
+ C c1; // expected-note {{jump bypasses variable initialization}}
+ lbl1: // expected-note {{possible target of indirect goto}}
+ return 0;
+ lbl2:
+ return 1;
+ }
+}
+
+namespace test5 {
+ struct C { C(); };
+ struct D { ~D(); };
+
+ int f(void **ip) {
+ static void *ips[] = { &&lbl1, &&lbl2 };
+ C c0;
+
+ goto *ip;
+ lbl1: // expected-note {{possible target of indirect goto}}
+ return 0;
+ lbl2:
+ if (ip[1]) {
+ D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+ ip += 2;
+ goto *ip; // expected-error {{indirect goto might cross protected scopes}}
+ }
+ return 1;
+ }
+}
+
+namespace test6 {
+ struct C { C(); };
+
+ unsigned f(unsigned s0, unsigned s1, void **ip) {
+ static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
+ C c0;
+
+ goto *ip;
+ lbl1:
+ s0++;
+ goto *++ip;
+ lbl2:
+ s0 -= s1;
+ goto *++ip;
+ lbl3: {
+ unsigned tmp = s0;
+ s0 = s1;
+ s1 = tmp;
+ goto *++ip;
+ }
+ lbl4:
+ return s0;
+ }
+}
+
+// C++0x says it's okay to skip non-trivial initializers on static
+// locals, and we implement that in '03 as well.
+namespace test7 {
+ struct C { C(); };
+
+ void test() {
+ goto foo;
+ static C c;
+ foo:
+ return;
+ }
+}
+
+// PR7789
+namespace test8 {
+ void test1(int c) {
+ switch (c) {
+ case 0:
+ int x = 56; // expected-note {{jump bypasses variable initialization}}
+ case 1: // expected-error {{switch case is in protected scope}}
+ x = 10;
+ }
+ }
+
+ void test2() {
+ goto l2; // expected-error {{goto into protected scope}}
+ l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
+ l2: x++;
+ }
+}
+
+namespace test9 {
+ struct S { int i; };
+ void test1() {
+ goto foo;
+ S s;
+ foo:
+ return;
+ }
+ unsigned test2(unsigned x, unsigned y) {
+ switch (x) {
+ case 2:
+ S s;
+ if (y > 42) return x + y;
+ default:
+ return x - 2;
+ }
+ }
+}
+
+// http://llvm.org/PR10462
+namespace PR10462 {
+enum MyEnum {
+ something_valid,
+ something_invalid
+};
+
+bool recurse() {
+ MyEnum K;
+ switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
+ case something_valid:
+ case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
+ int *X = 0;
+ if (recurse()) {
+ }
+
+ break;
+ }
+}
+
+
+namespace test10 {
+
+int test() {
+ static void *ps[] = { &&a0 };
+ goto *&&a0; // expected-error {{goto into protected scope}}
+ int a = 3; // expected-note {{jump bypasses variable initialization}}
+ a0:
+ return 0;
+}
+
+}
+
+}
+