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