blob: 933f1926c9d8c05251b866cbab53bf927c5cee5e [file]
// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -fclangir -emit-cir -std=c++17 -fcxx-exceptions -fexceptions -o %t.cir
// RUN: FileCheck -check-prefixes=CIR --input-file=%t.cir %s
// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -fclangir -emit-llvm -std=c++17 -fcxx-exceptions -fexceptions -o %t-cir.ll
// RUN: FileCheck -check-prefixes=LLVM --input-file=%t-cir.ll %s
// RUN: %clang_cc1 -no-enable-noundef-analysis %s -triple=x86_64-linux-gnu -emit-llvm -std=c++17 -fcxx-exceptions -fexceptions -o %t.ll
// RUN: FileCheck -check-prefixes=OGCG --input-file=%t.ll %s
struct S {
S();
~S();
operator bool();
};
S makeS();
void while_cond_cleanup(int n) {
while (makeS())
--n;
}
// CIR-LABEL: cir.func {{.*}} @_Z18while_cond_cleanupi
// CIR: cir.while {
// CIR: cir.call @_Z5makeSv()
// CIR: cir.cleanup.scope {
// CIR: cir.call @_ZN1ScvbEv(
// CIR: } cleanup all {
// CIR: cir.call @_ZN1SD1Ev({{.*}}) nothrow
// CIR: }
// CIR: cir.condition(
// CIR: } do {
// LLVM-LABEL: define dso_local void @_Z18while_cond_cleanupi(i32 %0) {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[TMP:.*]] = alloca %struct.S
// LLVM: call %struct.S @_Z5makeSv()
// LLVM: invoke i1 @_ZN1ScvbEv(ptr {{.*}} %[[TMP]])
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND:.*]]
// LLVM: [[CONT]]:
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: [[UNWIND]]:
// LLVM: landingpad { ptr, i32 }
// LLVM: cleanup
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: resume { ptr, i32 }
// LLVM: br i1
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z18while_cond_cleanupi(i32 %n) {{.*}} personality ptr @__gxx_personality_v0 {
// OGCG: while.cond:
// OGCG: %[[CALL:.*]] = invoke {{.*}} i1 @_ZN1ScvbEv(
// OGCG: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
// OGCG: [[CONT]]:
// OGCG: call void @_ZN1SD1Ev(
// OGCG: br i1 %[[CALL]], label %[[BODY:.*]], label %[[END:.*]]
// OGCG: [[BODY]]:
// OGCG: br label %while.cond
// OGCG: [[LPAD]]:
// OGCG: landingpad { ptr, i32 }
// OGCG: cleanup
// OGCG: call void @_ZN1SD1Ev(
// OGCG: [[END]]:
// OGCG: ret void
void do_while_cond_cleanup(int n) {
do {
--n;
} while (makeS());
}
// CIR-LABEL: cir.func {{.*}} @_Z21do_while_cond_cleanupi
// CIR: cir.do {
// CIR: cir.yield
// CIR: } while {
// CIR: cir.call @_Z5makeSv()
// CIR: cir.cleanup.scope {
// CIR: cir.call @_ZN1ScvbEv(
// CIR: } cleanup all {
// CIR: cir.call @_ZN1SD1Ev({{.*}}) nothrow
// CIR: }
// CIR: cir.condition(
// LLVM-LABEL: define dso_local void @_Z21do_while_cond_cleanupi(i32 %0) {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[TMP:.*]] = alloca %struct.S
// LLVM: call %struct.S @_Z5makeSv()
// LLVM: invoke i1 @_ZN1ScvbEv(ptr {{.*}} %[[TMP]])
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND:.*]]
// LLVM: [[CONT]]:
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: [[UNWIND]]:
// LLVM: landingpad { ptr, i32 }
// LLVM: cleanup
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: resume { ptr, i32 }
// LLVM: br i1
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z21do_while_cond_cleanupi(i32 %n) {{.*}} personality ptr @__gxx_personality_v0 {
// OGCG: do.cond:
// OGCG: %[[CALL:.*]] = invoke {{.*}} i1 @_ZN1ScvbEv(
// OGCG: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
// OGCG: [[CONT]]:
// OGCG: call void @_ZN1SD1Ev(
// OGCG: br i1 %[[CALL]]
// OGCG: ret void
// OGCG: [[LPAD]]:
// OGCG: landingpad { ptr, i32 }
// OGCG: cleanup
// OGCG: call void @_ZN1SD1Ev(
void for_cond_cleanup(int n) {
for (int i = 0; makeS(); ++i)
--n;
}
// CIR-LABEL: cir.func {{.*}} @_Z16for_cond_cleanupi
// CIR: cir.for : cond {
// CIR: cir.call @_Z5makeSv()
// CIR: cir.cleanup.scope {
// CIR: cir.call @_ZN1ScvbEv(
// CIR: } cleanup all {
// CIR: cir.call @_ZN1SD1Ev({{.*}}) nothrow
// CIR: }
// CIR: cir.condition(
// CIR: } body {
// LLVM-LABEL: define dso_local void @_Z16for_cond_cleanupi(i32 %0) {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[TMP:.*]] = alloca %struct.S
// LLVM: call %struct.S @_Z5makeSv()
// LLVM: invoke i1 @_ZN1ScvbEv(ptr {{.*}} %[[TMP]])
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND:.*]]
// LLVM: [[CONT]]:
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: [[UNWIND]]:
// LLVM: landingpad { ptr, i32 }
// LLVM: cleanup
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: resume { ptr, i32 }
// LLVM: br i1
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z16for_cond_cleanupi(i32 %n) {{.*}} personality ptr @__gxx_personality_v0 {
// OGCG: for.cond:
// OGCG: %[[CALL:.*]] = invoke {{.*}} i1 @_ZN1ScvbEv(
// OGCG: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
// OGCG: [[CONT]]:
// OGCG: call void @_ZN1SD1Ev(
// OGCG: br i1 %[[CALL]], label %[[BODY:.*]], label %[[END:.*]]
// OGCG: [[LPAD]]:
// OGCG: landingpad { ptr, i32 }
// OGCG: cleanup
// OGCG: call void @_ZN1SD1Ev(
// OGCG: [[END]]:
// OGCG: ret void
void for_step_cleanup(int n) {
for (int i = 0; i < n; (void)makeS())
--n;
}
// CIR-LABEL: cir.func {{.*}} @_Z16for_step_cleanupi
// CIR: cir.for : cond {
// CIR: } body {
// CIR: } step {
// CIR: cir.call @_Z5makeSv()
// CIR: cir.cleanup.scope {
// CIR: } cleanup all {
// CIR: cir.call @_ZN1SD1Ev({{.*}}) nothrow
// CIR: }
// CIR: }
// LLVM-LABEL: define dso_local void @_Z16for_step_cleanupi(i32 %0) {{.*}} {
// LLVM: %[[TMP:.*]] = alloca %struct.S
// LLVM: call %struct.S @_Z5makeSv()
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: br label
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z16for_step_cleanupi(i32 %n) {{.*}} {
// OGCG: for.inc:
// OGCG: call void @_Z5makeSv(
// OGCG: call void @_ZN1SD1Ev(
// OGCG: br label %for.cond
struct EndSentinel {};
struct Iter {
int operator*();
Iter &operator++();
};
S operator!=(Iter, EndSentinel);
struct Range {
Iter begin();
EndSentinel end();
};
Range getRange();
void range_for_cond_cleanup() {
for (int x : getRange()) {
(void)x;
}
}
// CIR-LABEL: cir.func {{.*}} @_Z22range_for_cond_cleanupv
// CIR: cir.for : cond {
// CIR: cir.call @_Zne4Iter11EndSentinel(
// CIR: cir.cleanup.scope {
// CIR: cir.call @_ZN1ScvbEv(
// CIR: } cleanup all {
// CIR: cir.call @_ZN1SD1Ev({{.*}}) nothrow
// CIR: }
// CIR: cir.condition(
// CIR: } body {
// LLVM-LABEL: define dso_local void @_Z22range_for_cond_cleanupv() {{.*}} personality ptr @__gxx_personality_v0 {
// LLVM: %[[TMP:.*]] = alloca %struct.S
// LLVM: call %struct.S @_Zne4Iter11EndSentinel(
// LLVM: invoke i1 @_ZN1ScvbEv(ptr {{.*}} %[[TMP]])
// LLVM: to label %[[CONT:.*]] unwind label %[[UNWIND:.*]]
// LLVM: [[CONT]]:
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: [[UNWIND]]:
// LLVM: landingpad { ptr, i32 }
// LLVM: cleanup
// LLVM: call void @_ZN1SD1Ev(ptr {{.*}} %[[TMP]])
// LLVM: resume { ptr, i32 }
// LLVM: br i1
// LLVM: ret void
// OGCG-LABEL: define dso_local void @_Z22range_for_cond_cleanupv() {{.*}} personality ptr @__gxx_personality_v0 {
// OGCG: for.cond:
// OGCG: %[[CALL:.*]] = invoke {{.*}} i1 @_ZN1ScvbEv(
// OGCG: to label %[[CONT:.*]] unwind label %[[LPAD:.*]]
// OGCG: [[CONT]]:
// OGCG: call void @_ZN1SD1Ev(
// OGCG: br i1 %[[CALL]], label %[[BODY:.*]], label %[[END:.*]]
// OGCG: [[LPAD]]:
// OGCG: landingpad { ptr, i32 }
// OGCG: cleanup
// OGCG: call void @_ZN1SD1Ev(
// OGCG: [[END]]:
// OGCG: ret void