// RUN: %clang_cc1 -emit-llvm -o - %s -triple x86_64-linux | FileCheck %s
struct A {
A();
A(const A &);
~A();
operator bool();
void *data;
};
A make();
bool cond();
void f(int);
// PR49585: Ensure that 'continue' performs the proper cleanups in the presence
// of a for loop condition variable.
//
// CHECK: define {{.*}} void @_Z7PR49585v(
void PR49585() {
for (
// CHECK: call void @_Z1fi(i32 noundef 1)
// CHECK: br label %[[for_cond:.*]]
f(1);
// CHECK: [[for_cond]]:
// CHECK: call {{.*}} @_Z4makev(
// CHECK: call {{.*}} @_ZN1AcvbEv(
// CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]]
A a = make();
// CHECK: [[for_cond_cleanup]]:
// CHECK: store
// CHECK: br label %[[cleanup:.*]]
f(2)) {
// CHECK: [[for_body]]:
// CHECK: call {{.*}} @_Z4condv(
// CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]]
if (cond()) {
// CHECK: [[if_then]]:
// CHECK: call {{.*}} @_Z1fi(i32 noundef 3)
// CHECK: br label %[[for_inc:.*]]
f(3);
continue;
}
// CHECK: [[if_end]]:
// CHECK: call {{.*}} @_Z1fi(i32 noundef 4)
// CHECK: br label %[[for_inc]]
f(4);
}
// CHECK: [[for_inc]]:
// CHECK: call void @_Z1fi(i32 noundef 2)
// CHECK: store
// CHECK: br label %[[cleanup]]
// CHECK: [[cleanup]]:
// CHECK: call void @_ZN1AD1Ev(
// CHECK: load
// CHECK: switch {{.*}} label
// CHECK-NEXT: label %[[cleanup_cont:.*]]
// CHECK-NEXT: label %[[for_end:.*]]
// CHECK: [[cleanup_cont]]:
// CHECK: br label %[[for_cond]]
// CHECK [[for_end]]:
// CHECK: ret void
}
// CHECK: define {{.*}} void @_Z13PR49585_breakv(
void PR49585_break() {
for (
// CHECK: call void @_Z1fi(i32 noundef 1)
// CHECK: br label %[[for_cond:.*]]
f(1);
// CHECK: [[for_cond]]:
// CHECK: call {{.*}} @_Z4makev(
// CHECK: call {{.*}} @_ZN1AcvbEv(
// CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_cond_cleanup:.*]]
A a = make();
// CHECK: [[for_cond_cleanup]]:
// CHECK: store
// CHECK: br label %[[cleanup:.*]]
f(2)) {
// CHECK: [[for_body]]:
// CHECK: call {{.*}} @_Z4condv(
// CHECK: br i1 {{.*}}, label %[[if_then:.*]], label %[[if_end:.*]]
if (cond()) {
// CHECK: [[if_then]]:
// CHECK: call {{.*}} @_Z1fi(i32 noundef 3)
// CHECK: store
// CHECK: br label %[[cleanup:.*]]
f(3);
break;
}
// CHECK: [[if_end]]:
// CHECK: call {{.*}} @_Z1fi(i32 noundef 4)
// CHECK: br label %[[for_inc]]
f(4);
}
// CHECK: [[for_inc]]:
// CHECK: call void @_Z1fi(i32 noundef 2)
// CHECK: store
// CHECK: br label %[[cleanup]]
// CHECK: [[cleanup]]:
// CHECK: call void @_ZN1AD1Ev(
// CHECK: load
// CHECK: switch {{.*}} label
// CHECK-NEXT: label %[[cleanup_cont:.*]]
// CHECK-NEXT: label %[[for_end:.*]]
// CHECK: [[cleanup_cont]]:
// CHECK: br label %[[for_cond]]
// CHECK [[for_end]]:
// CHECK: ret void
}
// CHECK: define {{.*}} void @_Z16incless_for_loopv(
void incless_for_loop() {
// CHECK: br label %[[for_cond:.*]]
// CHECK: [[for_cond]]:
// CHECK: br i1 {{.*}}, label %[[for_body:.*]], label %[[for_end:.*]]
// CHECK: [[for_body]]:
// CHECK: br label %[[for_cond]]
// CHECK: [[for_end]]:
// CHECK: ret void
// CHECK: }
for (; int b = 0;) continue;
}