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