================
@@ -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

Reply via email to