blob: bc58d2193c267f330bcc636f6d807f1aff71b8e0 [file]
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
// RUN: cir-opt --cir-flatten-cfg %t.cir -o %t-flat.cir
// RUN: FileCheck --input-file=%t-flat.cir %s --check-prefix=CIR-FLAT
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
struct S {
int data[5];
void method();
int &ref_return();
void ref_param(int &i);
};
// Test that 'this' pointer attributes (nonnull, noundef, align,
// dereferenceable) are preserved on invoke instructions lowered from
// calls inside try blocks.
void test_this_ptr_attrs(S &s) {
try {
s.method();
} catch (...) {}
}
// CIR-LABEL: cir.func {{.*}}@_Z19test_this_ptr_attrsR1S
// CIR: cir.call @_ZN1S6methodEv({{%.*}}) : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> ()
// CIR-FLAT-LABEL: cir.func {{.*}}@_Z19test_this_ptr_attrsR1S
// CIR-FLAT: cir.try_call @_ZN1S6methodEv({{%.*}}) ^{{bb[0-9]+}}, ^{{bb[0-9]+}} : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> ()
// LLVM-LABEL: define {{.*}} void @_Z19test_this_ptr_attrsR1S
// LLVM: invoke void @_ZN1S6methodEv(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}})
// OGCG-LABEL: define {{.*}} void @_Z19test_this_ptr_attrsR1S
// OGCG: invoke void @_ZN1S6methodEv(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}})
// Test that both 'this' and reference parameter attributes are preserved
// on invoke instructions.
void test_ref_param_attrs(S &s, int &i) {
try {
s.ref_param(i);
} catch (...) {}
}
// CIR-LABEL: cir.func {{.*}}@_Z20test_ref_param_attrsR1SRi
// CIR: cir.call @_ZN1S9ref_paramERi({{%.*}}, {{%.*}}) : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}, !cir.ptr<!s32i> {llvm.align = 8 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef}) -> ()
// CIR-FLAT-LABEL: cir.func {{.*}}@_Z20test_ref_param_attrsR1SRi
// CIR-FLAT: cir.try_call @_ZN1S9ref_paramERi({{%.*}}, {{%.*}}) ^{{bb[0-9]+}}, ^{{bb[0-9]+}} : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}, !cir.ptr<!s32i> {llvm.align = 8 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef}) -> ()
// LLVM-LABEL: define {{.*}} void @_Z20test_ref_param_attrsR1SRi
// LLVM: invoke void @_ZN1S9ref_paramERi(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}}, ptr noundef nonnull align 8 dereferenceable(4) {{%.*}})
// OGCG-LABEL: define {{.*}} void @_Z20test_ref_param_attrsR1SRi
// OGCG: invoke void @_ZN1S9ref_paramERi(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}}, ptr noundef nonnull align 4 dereferenceable(4) {{%.*}})
// Test that return attributes (nonnull, noundef, align, dereferenceable)
// and parameter attributes are preserved on invoke instructions that
// return a value.
void test_ref_return_attrs(S &s) {
try {
int &r = s.ref_return();
} catch (...) {}
}
// CIR-LABEL: cir.func {{.*}}@_Z21test_ref_return_attrsR1S
// CIR: cir.call @_ZN1S10ref_returnEv({{%.*}}) : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> (!cir.ptr<!s32i> {llvm.align = 4 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef})
// CIR-FLAT-LABEL: cir.func {{.*}}@_Z21test_ref_return_attrsR1S
// CIR-FLAT: cir.try_call @_ZN1S10ref_returnEv({{%.*}}) ^{{bb[0-9]+}}, ^{{bb[0-9]+}} : (!cir.ptr<!rec_S> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> (!cir.ptr<!s32i> {llvm.align = 4 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef})
// LLVM-LABEL: define {{.*}} void @_Z21test_ref_return_attrsR1S
// LLVM: {{%.*}} = invoke noundef nonnull align 4 dereferenceable(4) ptr @_ZN1S10ref_returnEv(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}})
// OGCG-LABEL: define {{.*}} void @_Z21test_ref_return_attrsR1S
// OGCG: {{%.*}} = invoke noundef nonnull align 4 dereferenceable(4) ptr @_ZN1S10ref_returnEv(ptr noundef nonnull align 4 dereferenceable(20) {{%.*}})