1 | // RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -fmerge-all-constants -emit-llvm -o - %s | FileCheck %s |
2 | |
3 | namespace reference { |
4 | struct A { |
5 | int i1, i2; |
6 | }; |
7 | |
8 | void single_init() { |
9 | // No superfluous instructions allowed here, they could be |
10 | // hiding extra temporaries. |
11 | |
12 | // CHECK: store i32 1, i32* |
13 | // CHECK-NEXT: store i32* %{{.*}}, i32** |
14 | const int &cri2a = 1; |
15 | |
16 | // CHECK-NEXT: store i32 1, i32* |
17 | // CHECK-NEXT: store i32* %{{.*}}, i32** |
18 | const int &cri1a = {1}; |
19 | |
20 | // CHECK-NEXT: store i32 1, i32* |
21 | int i = 1; |
22 | // CHECK-NEXT: store i32* %{{.*}}, i32** |
23 | int &ri1a = {i}; |
24 | |
25 | // CHECK-NEXT: bitcast |
26 | // CHECK-NEXT: memcpy |
27 | A a{1, 2}; |
28 | // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % |
29 | A &ra1a = {a}; |
30 | |
31 | using T = A&; |
32 | // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % |
33 | A &ra1b = T{a}; |
34 | |
35 | // CHECK-NEXT: ret |
36 | } |
37 | |
38 | void reference_to_aggregate(int i) { |
39 | // CHECK: getelementptr {{.*}}, i32 0, i32 0 |
40 | // CHECK-NEXT: store i32 1 |
41 | // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1 |
42 | // CHECK-NEXT: %[[I1:.*]] = load i32, i32* |
43 | // CHECK-NEXT: store i32 %[[I1]] |
44 | // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align |
45 | const A &ra1{1, i}; |
46 | |
47 | // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 |
48 | // CHECK-NEXT: store i32 1 |
49 | // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1 |
50 | // CHECK-NEXT: store i32 2 |
51 | // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1 |
52 | // CHECK-NEXT: %[[I2:.*]] = load i32, i32* |
53 | // CHECK-NEXT: store i32 %[[I2]] |
54 | // CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align |
55 | const int (&arrayRef)[] = {1, 2, i}; |
56 | |
57 | // CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align |
58 | const A &constra1{1, 2}; |
59 | |
60 | // CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align |
61 | const int (&constarrayRef)[] = {1, 2, 3}; |
62 | |
63 | // CHECK-NEXT: ret |
64 | } |
65 | |
66 | struct B { |
67 | B(); |
68 | ~B(); |
69 | }; |
70 | |
71 | void single_init_temp_cleanup() |
72 | { |
73 | // Ensure lifetime extension. |
74 | |
75 | // CHECK: call %"struct.reference::B"* @_ZN9reference1BC1Ev |
76 | // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** % |
77 | const B &rb{ B() }; |
78 | // CHECK: call %"struct.reference::B"* @_ZN9reference1BD1Ev |
79 | } |
80 | |
81 | } |
82 | |
83 | namespace PR23165 { |
84 | struct AbstractClass { |
85 | virtual void foo() const = 0; |
86 | }; |
87 | |
88 | struct ChildClass : public AbstractClass { |
89 | virtual void foo() const {} |
90 | }; |
91 | |
92 | void helper(const AbstractClass ¶m) { |
93 | param.foo(); |
94 | } |
95 | |
96 | void foo() { |
97 | // CHECK-LABEL: @_ZN7PR231653fooEv |
98 | // CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev |
99 | // CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE |
100 | helper(ChildClass()); |
101 | } |
102 | |
103 | struct S { struct T { int a; } t; mutable int b; }; |
104 | void f() { |
105 | // CHECK-LABEL: _ZN7PR231651fEv |
106 | // CHECK: alloca |
107 | // CHECK: alloca |
108 | // CHECK: store |
109 | const S::T &r = S().t; |
110 | } |
111 | } |
112 | |