1 | // RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s |
2 | |
3 | // PR6024 |
4 | extern int i; |
5 | |
6 | // CHECK: define dereferenceable({{[0-9]+}}) i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]] |
7 | const int &lvalue_noop_cast() { |
8 | if (i == 0) |
9 | // CHECK: store i32 17, i32* |
10 | return (const int&)17; |
11 | else if (i == 1) |
12 | // CHECK: store i32 17, i32* |
13 | return static_cast<const int&>(17); |
14 | // CHECK: store i32 17, i32* |
15 | return 17; |
16 | } |
17 | |
18 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z20lvalue_integral_castv() |
19 | const short &lvalue_integral_cast() { |
20 | if (i == 0) |
21 | // CHECK: store i16 17, i16* |
22 | return (const short&)17; |
23 | else if (i == 1) |
24 | // CHECK: store i16 17, i16* |
25 | return static_cast<const short&>(17); |
26 | // CHECK: store i16 17, i16* |
27 | return 17; |
28 | } |
29 | |
30 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z29lvalue_floating_integral_castv() |
31 | const short &lvalue_floating_integral_cast() { |
32 | if (i == 0) |
33 | // CHECK: store i16 17, i16* |
34 | return (const short&)17.5; |
35 | else if (i == 1) |
36 | // CHECK: store i16 17, i16* |
37 | return static_cast<const short&>(17.5); |
38 | // CHECK: store i16 17, i16* |
39 | return 17.5; |
40 | } |
41 | |
42 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z29lvalue_integral_floating_castv() |
43 | const float &lvalue_integral_floating_cast() { |
44 | if (i == 0) |
45 | // CHECK: store float 1.700000e+{{0*}}1, float* |
46 | return (const float&)17; |
47 | else if (i == 1) |
48 | // CHECK: store float 1.700000e+{{0*}}1, float* |
49 | return static_cast<const float&>(17); |
50 | // CHECK: store float 1.700000e+{{0*}}1, float* |
51 | return 17; |
52 | } |
53 | |
54 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z20lvalue_floating_castv() |
55 | const float &lvalue_floating_cast() { |
56 | if (i == 0) |
57 | // CHECK: store float 1.700000e+{{0*}}1, float* |
58 | return (const float&)17.0; |
59 | else if (i == 1) |
60 | // CHECK: store float 1.700000e+{{0*}}1, float* |
61 | return static_cast<const float&>(17.0); |
62 | // CHECK: store float 1.700000e+{{0*}}1, float* |
63 | return 17.0; |
64 | } |
65 | |
66 | int get_int(); |
67 | |
68 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z24lvalue_integer_bool_castv() |
69 | const bool &lvalue_integer_bool_cast() { |
70 | if (i == 0) |
71 | // CHECK: call i32 @_Z7get_intv() |
72 | // CHECK: store i8 |
73 | return (const bool&)get_int(); |
74 | else if (i == 1) |
75 | // CHECK: call i32 @_Z7get_intv() |
76 | // CHECK: store i8 |
77 | return static_cast<const bool&>(get_int()); |
78 | // CHECK: call i32 @_Z7get_intv() |
79 | // CHECK: store i8 |
80 | return get_int(); |
81 | } |
82 | |
83 | float get_float(); |
84 | |
85 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z25lvalue_floating_bool_castv() |
86 | const bool &lvalue_floating_bool_cast() { |
87 | if (i == 0) |
88 | // CHECK: call float @_Z9get_floatv() |
89 | // CHECK: fcmp une float |
90 | // CHECK: store i8 |
91 | return (const bool&)get_float(); |
92 | else if (i == 1) |
93 | // CHECK: call float @_Z9get_floatv() |
94 | // CHECK: fcmp une float |
95 | // CHECK: store i8 |
96 | return static_cast<const bool&>(get_float()); |
97 | // CHECK: call float @_Z9get_floatv() |
98 | // CHECK: fcmp une float |
99 | // CHECK: store i8 |
100 | return get_float(); |
101 | } |
102 | |
103 | struct X { }; |
104 | typedef int X::*pm; |
105 | typedef int (X::*pmf)(int); |
106 | |
107 | pm get_pointer_to_member_data(); |
108 | pmf get_pointer_to_member_function(); |
109 | |
110 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z26lvalue_ptrmem_to_bool_castv() |
111 | const bool &lvalue_ptrmem_to_bool_cast() { |
112 | if (i == 0) |
113 | // CHECK: call i64 @_Z26get_pointer_to_member_datav() |
114 | // CHECK: store i8 |
115 | // CHECK: store i8* |
116 | return (const bool&)get_pointer_to_member_data(); |
117 | else if (i == 1) |
118 | // CHECK: call i64 @_Z26get_pointer_to_member_datav() |
119 | // CHECK: store i8 |
120 | // CHECK: store i8* |
121 | return static_cast<const bool&>(get_pointer_to_member_data()); |
122 | // CHECK: call i64 @_Z26get_pointer_to_member_datav() |
123 | // CHECK: store i8 |
124 | // CHECK: store i8* |
125 | return get_pointer_to_member_data(); |
126 | } |
127 | |
128 | // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z27lvalue_ptrmem_to_bool_cast2v |
129 | const bool &lvalue_ptrmem_to_bool_cast2() { |
130 | if (i == 0) |
131 | // CHECK: {{call.*_Z30get_pointer_to_member_functionv}} |
132 | // CHECK: store i8 |
133 | // CHECK: store i8* |
134 | return (const bool&)get_pointer_to_member_function(); |
135 | else if (i == 1) |
136 | // CHECK: {{call.*_Z30get_pointer_to_member_functionv}} |
137 | // CHECK: store i8 |
138 | // CHECK: store i8* |
139 | return static_cast<const bool&>(get_pointer_to_member_function()); |
140 | // CHECK: {{call.*_Z30get_pointer_to_member_functionv}} |
141 | // CHECK: store i8 |
142 | // CHECK: store i8* |
143 | return get_pointer_to_member_function(); |
144 | } |
145 | |
146 | _Complex double get_complex_double(); |
147 | |
148 | // CHECK: {{define.*_Z2f1v}} |
149 | const _Complex float &f1() { |
150 | if (i == 0) |
151 | // CHECK: {{call.*_Z18get_complex_doublev}} |
152 | // CHECK: fptrunc |
153 | // CHECK: fptrunc |
154 | // CHECK: store float |
155 | // CHECK: store float |
156 | return (const _Complex float&)get_complex_double(); |
157 | else if (i == 1) |
158 | // CHECK: {{call.*_Z18get_complex_doublev}} |
159 | // CHECK: fptrunc |
160 | // CHECK: fptrunc |
161 | // CHECK: store float |
162 | // CHECK: store float |
163 | return static_cast<const _Complex float&>(get_complex_double()); |
164 | // CHECK: {{call.*_Z18get_complex_doublev}} |
165 | // CHECK: fptrunc |
166 | // CHECK: fptrunc |
167 | // CHECK: store float |
168 | // CHECK: store float |
169 | return get_complex_double(); |
170 | } |
171 | |
172 | // CHECK-LABEL: define i32 @_Z7pr10592RKi(i32* |
173 | unsigned pr10592(const int &v) { |
174 | // CHECK: [[VADDR:%[a-zA-Z0-9.]+]] = alloca i32* |
175 | // CHECK-NEXT: [[REFTMP:%[a-zA-Z0-9.]+]] = alloca i32 |
176 | // CHECK-NEXT: store i32* [[V:%[a-zA-Z0-9.]+]], i32** [[VADDR]] |
177 | // CHECK-NEXT: [[VADDR_1:%[a-zA-Z0-9.]+]] = load i32*, i32** [[VADDR]] |
178 | // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32, i32* [[VADDR_1]] |
179 | // CHECK-NEXT: store i32 [[VVAL]], i32* [[REFTMP]] |
180 | // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32, i32* [[REFTMP]] |
181 | // CHECK-NEXT: ret i32 [[VVAL_I]] |
182 | return static_cast<const unsigned &>(v); |
183 | } |
184 | |
185 | namespace PR10650 { |
186 | struct Helper { |
187 | unsigned long long id(); |
188 | }; |
189 | unsigned long long test(Helper *obj) { |
190 | return static_cast<const unsigned long long&>(obj->id()); |
191 | } |
192 | // CHECK-LABEL: define i64 @_ZN7PR106504testEPNS_6HelperE |
193 | // CHECK: store i64 |
194 | } |
195 | |
196 | // CHECK: attributes [[NUW]] = { noinline nounwind{{.*}} } |
197 | |