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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
lvalue_noop_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i16* @_Z20lvalue_integral_castv()
lvalue_integral_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i16* @_Z29lvalue_floating_integral_castv()
lvalue_floating_integral_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) float* @_Z29lvalue_integral_floating_castv()
lvalue_integral_floating_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) float* @_Z20lvalue_floating_castv()
lvalue_floating_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8* @_Z24lvalue_integer_bool_castv()
lvalue_integer_bool_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8* @_Z25lvalue_floating_bool_castv()
lvalue_floating_bool_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8* @_Z26lvalue_ptrmem_to_bool_castv()
lvalue_ptrmem_to_bool_cast()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{{.*}} nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) i8* @_Z27lvalue_ptrmem_to_bool_cast2v
lvalue_ptrmem_to_bool_cast2()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}}
f1()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*
pr10592(const int & v)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   };
test(Helper * obj)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]] = { mustprogress noinline nounwind{{.*}} }
197