[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGenCXX / pass-by-value-noalias.cpp
blob765a6fb66a72bc5691f8110a7d24b61aa9053b94
1 // RUN: %clang_cc1 -fpass-by-value-is-noalias -triple arm64-apple-iphoneos -emit-llvm -disable-llvm-optzns %s -o - 2>&1 | FileCheck --check-prefix=WITH_NOALIAS %s
2 // RUN: %clang_cc1 -triple arm64-apple-iphoneos -emit-llvm -disable-llvm-optzns %s -o - 2>&1 | FileCheck --check-prefix=NO_NOALIAS %s
4 // A trivial struct large enough so it is not passed in registers on ARM64.
5 struct Foo {
6 int a;
7 int b;
8 int c;
9 int d;
10 int e;
11 int f;
14 // Make sure noalias is added to indirect arguments with trivially copyable types
15 // if -fpass-by-value-is-noalias is provided.
17 // WITH_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr noalias noundef %arg)
18 // NO_NOALIAS: define{{.*}} void @_Z4take3Foo(ptr noundef %arg)
19 void take(Foo arg) {}
21 int G;
23 // NonTrivial is not trivially-copyable, because it has a non-trivial copy
24 // constructor.
25 struct NonTrivial {
26 int a;
27 int b;
28 int c;
29 int d;
30 int e;
31 int f;
33 NonTrivial(const NonTrivial &Other) {
34 a = G + 10 + Other.a;
38 // Make sure noalias is not added to indirect arguments that are not trivially
39 // copyable even if -fpass-by-value-is-noalias is provided.
41 // WITH_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr noundef %arg)
42 // NO_NOALIAS: define{{.*}} void @_Z4take10NonTrivial(ptr noundef %arg)
43 void take(NonTrivial arg) {}
45 // Escape examples. Pointers to the objects passed to take() may escape, depending on whether a temporary copy is created or not (e.g. due to NRVO).
46 struct A {
47 A(A **where) : data{"hello world 1"} {
48 *where = this; //Escaped pointer 1 (proposed UB?)
51 A() : data{"hello world 2"} {}
53 char data[32];
55 A *p;
57 // WITH_NOALIAS: define{{.*}} void @_Z4take1A(ptr noalias noundef %arg)
58 // NO_NOALIAS: define{{.*}} void @_Z4take1A(ptr noundef %arg)
59 void take(A arg) {}
61 // WITH_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr noalias sret(%struct.A) align 1 %agg.result, ptr noundef %where)
62 // NO_NOALIAS: define{{.*}} void @_Z7CreateAPP1A(ptr noalias sret(%struct.A) align 1 %agg.result, ptr noundef %where)
63 A CreateA(A **where) {
64 A justlikethis;
65 *where = &justlikethis; //Escaped pointer 2 (should also be UB, then)
66 return justlikethis;
69 // elsewhere, perhaps compiled by a smarter compiler that doesn't make a copy here
70 void test() {
71 take({&p}); // 1
72 take(CreateA(&p)); // 2