// 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; }