================
@@ -318,6 +309,262 @@ void test_huge_larger_init() {
used(big);
}
+// UNINIT-LABEL: test_goto_multiple_bypassed(
+// ZERO-LABEL: test_goto_multiple_bypassed(
+// ZERO: %a = alloca i32, align 4
+// ZERO: %b = alloca i32, align 4
+// ZERO-DAG: store i32 0, ptr %a, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO-DAG: store i32 0, ptr %b, align 4, !annotation [[AUTO_INIT:!.+]]
+// PATTERN-LABEL: test_goto_multiple_bypassed(
+// PATTERN: %a = alloca i32, align 4
+// PATTERN: %b = alloca i32, align 4
+// PATTERN-DAG: store i32 -1431655766, ptr %a, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN-DAG: store i32 -1431655766, ptr %b, align 4, !annotation
[[AUTO_INIT:!.+]]
+void test_goto_multiple_bypassed() {
+ goto jump;
+ int a;
+ int b;
+ jump:
+ used(a);
+ used(b);
+}
+
+// UNINIT-LABEL: test_goto_bypassed_uninitialized_attr(
+// ZERO-LABEL: test_goto_bypassed_uninitialized_attr(
+// ZERO-NOT: store {{.*}}%skip_me
+// ZERO: call void @{{.*}}used
+// PATTERN-LABEL: test_goto_bypassed_uninitialized_attr(
+// PATTERN-NOT: store {{.*}}%skip_me
+// PATTERN: call void @{{.*}}used
+void test_goto_bypassed_uninitialized_attr() {
+ goto jump;
+ [[clang::uninitialized]] int skip_me;
+ jump:
+ used(skip_me);
+}
+
+// UNINIT-LABEL: test_switch_between_cases(
+// ZERO-LABEL: test_switch_between_cases(
+// ZERO: %x = alloca i32, align 4
+// ZERO: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// PATTERN-LABEL: test_switch_between_cases(
+// PATTERN: %x = alloca i32, align 4
+// PATTERN: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+void test_switch_between_cases(int c) {
+ switch (c) {
+ case 0:
+ int x;
+ x = 42;
+ used(x);
+ break;
+ case 1:
+ used(x);
+ break;
+ }
+}
+
+// UNINIT-LABEL: test_switch_precase(
+// ZERO-LABEL: test_switch_precase(
+// ZERO: %x = alloca i32, align 4
+// ZERO: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// PATTERN-LABEL: test_switch_precase(
+// PATTERN: %x = alloca i32, align 4
+// PATTERN: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+void test_switch_precase(int c) {
+ switch (c) {
+ int x;
+ case 0:
+ x = 1;
+ used(x);
+ break;
+ }
+}
+
+// UNINIT-LABEL: test_computed_goto(
+// ZERO-LABEL: test_computed_goto(
+// ZERO: %y = alloca i32, align 4
+// ZERO: store i32 0, ptr %y, align 4, !annotation [[AUTO_INIT:!.+]]
+// PATTERN-LABEL: test_computed_goto(
+// PATTERN: %y = alloca i32, align 4
+// PATTERN: store i32 -1431655766, ptr %y, align 4, !annotation
[[AUTO_INIT:!.+]]
+void test_computed_goto(int x) {
+ void *targets[] = {&&label1, &&label2};
+ goto *targets[x];
+ int y;
+label1:
+ used(y);
+ return;
+label2:
+ return;
+}
+
+// UNINIT-LABEL: test_loop_bypass(
+// ZERO-LABEL: test_loop_bypass(
+// ZERO: %x = alloca i32, align 4
+// ZERO: while.body:
+// ZERO: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO: br label %X
+// PATTERN-LABEL: test_loop_bypass(
+// PATTERN: %x = alloca i32, align 4
+// PATTERN: while.body:
+// PATTERN: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN: br label %X
+void test_loop_bypass() {
+ while (true) {
+ goto X;
+ int x;
+ X:
+ used(x);
+ if (x) break;
+ }
+}
+
+// UNINIT-LABEL: test_complex_multi_goto(
+// ZERO-LABEL: test_complex_multi_goto(
+// ZERO: Z:
+// ZERO-NEXT: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO-NEXT: br label %Y
+// ZERO: X:
+// ZERO-NEXT: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO-NEXT: br label %Y
+// ZERO: sw.bb:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: br label %X
+// ZERO: sw.bb1:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: br label %Z
+// ZERO: sw.epilog:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: br label %Y
+// PATTERN-LABEL: test_complex_multi_goto(
+// PATTERN: Z:
+// PATTERN-NEXT: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN-NEXT: br label %Y
+// PATTERN: X:
+// PATTERN-NEXT: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN-NEXT: br label %Y
+// PATTERN: sw.bb:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: br label %X
+// PATTERN: sw.bb1:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: br label %Z
+// PATTERN: sw.epilog:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: br label %Y
+void test_complex_multi_goto(int g(int*)) {
+ while (true) {
+ Z:
+ goto Y;
+ X:
+ goto Y;
+ int x;
+ Y:
+ switch (g(&x)) {
+ case 0:
+ goto X;
+ case 1:
+ goto Z;
+ }
+ goto Y;
+ }
+}
+
+// UNINIT-LABEL: test_no_reinit_in_scope(
+// ZERO-LABEL: test_no_reinit_in_scope(
+// ZERO: while.body:
+// ZERO-NEXT: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO-NEXT: br label %Y
+// ZERO: if.end:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: br label %Y
+// PATTERN-LABEL: test_no_reinit_in_scope(
+// PATTERN: while.body:
+// PATTERN-NEXT: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN-NEXT: br label %Y
+// PATTERN: if.end:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: br label %Y
+void test_no_reinit_in_scope(int g(int*)) {
+ while (true) {
+ goto Y;
+ int x;
+ Y:
+ if (g(&x))
+ break;
+ goto Y;
+ }
+}
+
+// Backward goto: x is already in scope, no bypass init should occur at the
+// goto.
+// UNINIT-LABEL: test_backward_goto_no_init(
+// ZERO-LABEL: test_backward_goto_no_init(
+// ZERO: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO: L:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: if.then:
+// ZERO-NOT: store {{.*}}%x
+// ZERO: br label %L
+// PATTERN-LABEL: test_backward_goto_no_init(
+// PATTERN: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN: L:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: if.then:
+// PATTERN-NOT: store {{.*}}%x
+// PATTERN: br label %L
+void test_backward_goto_no_init() {
+ int x;
+ L:
+ used(x);
+ if (x)
+ goto L;
+}
+
+// Switch with default case bypassing a variable declared in case 0.
+// UNINIT-LABEL: test_switch_default_bypass(
+// ZERO-LABEL: test_switch_default_bypass(
+// ZERO: sw.default:
+// ZERO-NEXT: store i32 0, ptr %x, align 4, !annotation [[AUTO_INIT:!.+]]
+// PATTERN-LABEL: test_switch_default_bypass(
+// PATTERN: sw.default:
+// PATTERN-NEXT: store i32 -1431655766, ptr %x, align 4, !annotation
[[AUTO_INIT:!.+]]
+void test_switch_default_bypass(int c) {
+ switch (c) {
+ case 0:
+ int x;
+ x = 10;
+ used(x);
+ break;
+ default:
+ used(x);
+ break;
+ }
+}
+
+// Multipe variables bypassed by the same goto so both must be initialized.
+// UNINIT-LABEL: test_goto_multiple_vars(
+// ZERO-LABEL: test_goto_multiple_vars(
+// ZERO: %a = alloca i32, align 4
+// ZERO: %b = alloca i32, align 4
+// ZERO: store i32 0, ptr %a, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO: store i32 0, ptr %b, align 4, !annotation [[AUTO_INIT:!.+]]
+// ZERO: br label %jump
+// PATTERN-LABEL: test_goto_multiple_vars(
+// PATTERN: %a = alloca i32, align 4
+// PATTERN: %b = alloca i32, align 4
+// PATTERN: store i32 -1431655766, ptr %a, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN: store i32 -1431655766, ptr %b, align 4, !annotation
[[AUTO_INIT:!.+]]
+// PATTERN: br label %jump
+void test_goto_multiple_vars() {
+ goto jump;
+ int a;
+ int b;
+ jump:
+ used(a);
+ used(b);
+}
+
} // extern "C"
// CHECK: [[AUTO_INIT]] = !{ !"auto-init" }
----------------
efriedma-quic wrote:
Please make sure we have coverage for a bypassing backwards goto:
```
void test() {
{
int a;
int b;
jump:
used(a);
used(b);
}
goto jump;
}
```
https://github.com/llvm/llvm-project/pull/181937
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits