1// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s
2
3// PR6024
4extern int i;
5
6// CHECK: define nonnull i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
7const 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 i16* @_Z20lvalue_integral_castv()
19const 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 i16* @_Z29lvalue_floating_integral_castv()
31const 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 float* @_Z29lvalue_integral_floating_castv()
43const 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 float* @_Z20lvalue_floating_castv()
55const 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
66int get_int();
67
68// CHECK-LABEL: define nonnull i8* @_Z24lvalue_integer_bool_castv()
69const 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
83float get_float();
84
85// CHECK-LABEL: define nonnull i8* @_Z25lvalue_floating_bool_castv()
86const 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
103struct X { };
104typedef int X::*pm;
105typedef int (X::*pmf)(int);
106
107pm get_pointer_to_member_data();
108pmf get_pointer_to_member_function();
109
110// CHECK-LABEL: define nonnull i8* @_Z26lvalue_ptrmem_to_bool_castv()
111const 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 i8* @_Z27lvalue_ptrmem_to_bool_cast2v
129const 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}}
149const _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*
173unsigned 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** [[VADDR]]
178  // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32* [[VADDR_1]]
179  // CHECK-NEXT: store i32 [[VVAL]], i32* [[REFTMP]]
180  // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32* [[REFTMP]]
181  // CHECK-NEXT: ret i32 [[VVAL_I]]
182  return static_cast<const unsigned &>(v);
183}
184
185namespace 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]] = { nounwind{{.*}} }
197