1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
2f4a2713aSLionel Sambuc // rdar: // 8353567
3f4a2713aSLionel Sambuc // pr7726
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc extern "C" int printf(...);
6f4a2713aSLionel Sambuc
test0()7f4a2713aSLionel Sambuc void test0() {
8f4a2713aSLionel Sambuc // CHECK: call i32 (...)* @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*))
9f4a2713aSLionel Sambuc printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa);
10f4a2713aSLionel Sambuc }
11f4a2713aSLionel Sambuc
12f4a2713aSLionel Sambuc // rdar://8446940
13f4a2713aSLionel Sambuc namespace radar8446940 {
14f4a2713aSLionel Sambuc extern "C" void abort();
15f4a2713aSLionel Sambuc
main()16f4a2713aSLionel Sambuc int main () {
17f4a2713aSLionel Sambuc char x[1];
18f4a2713aSLionel Sambuc char *y = x ? : 0;
19f4a2713aSLionel Sambuc
20f4a2713aSLionel Sambuc if (x != y)
21f4a2713aSLionel Sambuc abort();
22f4a2713aSLionel Sambuc }
23f4a2713aSLionel Sambuc }
24f4a2713aSLionel Sambuc
25f4a2713aSLionel Sambuc namespace radar8453812 {
26f4a2713aSLionel Sambuc extern "C" void abort();
getComplex(_Complex int val)27f4a2713aSLionel Sambuc _Complex int getComplex(_Complex int val) {
28f4a2713aSLionel Sambuc static int count;
29f4a2713aSLionel Sambuc if (count++)
30f4a2713aSLionel Sambuc abort();
31f4a2713aSLionel Sambuc return val;
32f4a2713aSLionel Sambuc }
33f4a2713aSLionel Sambuc
cmplx()34f4a2713aSLionel Sambuc _Complex int cmplx() {
35f4a2713aSLionel Sambuc _Complex int cond;
36f4a2713aSLionel Sambuc _Complex int rhs;
37f4a2713aSLionel Sambuc
38f4a2713aSLionel Sambuc return getComplex(1+2i) ? : rhs;
39f4a2713aSLionel Sambuc }
40f4a2713aSLionel Sambuc
41f4a2713aSLionel Sambuc // lvalue test
foo(int & lv)42f4a2713aSLionel Sambuc void foo (int& lv) {
43f4a2713aSLionel Sambuc ++lv;
44f4a2713aSLionel Sambuc }
45f4a2713aSLionel Sambuc
46f4a2713aSLionel Sambuc int global = 1;
47f4a2713aSLionel Sambuc
cond()48f4a2713aSLionel Sambuc int &cond() {
49f4a2713aSLionel Sambuc static int count;
50f4a2713aSLionel Sambuc if (count++)
51f4a2713aSLionel Sambuc abort();
52f4a2713aSLionel Sambuc return global;
53f4a2713aSLionel Sambuc }
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc
main()56f4a2713aSLionel Sambuc int main() {
57f4a2713aSLionel Sambuc cmplx();
58f4a2713aSLionel Sambuc int rhs = 10;
59f4a2713aSLionel Sambuc foo (cond()? : rhs);
60f4a2713aSLionel Sambuc return global-2;
61f4a2713aSLionel Sambuc }
62f4a2713aSLionel Sambuc }
63f4a2713aSLionel Sambuc
64f4a2713aSLionel Sambuc namespace test3 {
65f4a2713aSLionel Sambuc struct A {
66f4a2713aSLionel Sambuc A();
67f4a2713aSLionel Sambuc A(const A&);
68f4a2713aSLionel Sambuc ~A();
69f4a2713aSLionel Sambuc };
70f4a2713aSLionel Sambuc
71f4a2713aSLionel Sambuc struct B {
72f4a2713aSLionel Sambuc B();
73f4a2713aSLionel Sambuc B(const B&);
74f4a2713aSLionel Sambuc ~B();
75f4a2713aSLionel Sambuc operator bool();
76f4a2713aSLionel Sambuc operator A();
77f4a2713aSLionel Sambuc };
78f4a2713aSLionel Sambuc
test0(B & x)79f4a2713aSLionel Sambuc B test0(B &x) {
80f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test35test0ERNS_1BE(
81f4a2713aSLionel Sambuc // CHECK: [[X:%.*]] = alloca [[B:%.*]]*,
82f4a2713aSLionel Sambuc // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
83f4a2713aSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
84f4a2713aSLionel Sambuc // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
85f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[BOOL]]
86*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[T0]])
87f4a2713aSLionel Sambuc // CHECK-NEXT: br label
88f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
89f4a2713aSLionel Sambuc // CHECK-NEXT: br label
90f4a2713aSLionel Sambuc // CHECK: ret void
91f4a2713aSLionel Sambuc return x ?: B();
92f4a2713aSLionel Sambuc }
93f4a2713aSLionel Sambuc
test1()94f4a2713aSLionel Sambuc B test1() {
95f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test35test1Ev(
96f4a2713aSLionel Sambuc // CHECK: [[TEMP:%.*]] = alloca [[B]],
97f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]])
98f4a2713aSLionel Sambuc // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
99f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[BOOL]]
100*0a6a1f1dSLionel Sambuc // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[TEMP]])
101f4a2713aSLionel Sambuc // CHECK-NEXT: br label
102f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
103f4a2713aSLionel Sambuc // CHECK-NEXT: br label
104f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
105f4a2713aSLionel Sambuc // CHECK-NEXT: ret void
106f4a2713aSLionel Sambuc extern B test1_helper();
107f4a2713aSLionel Sambuc return test1_helper() ?: B();
108f4a2713aSLionel Sambuc }
109f4a2713aSLionel Sambuc
110f4a2713aSLionel Sambuc
test2(B & x)111f4a2713aSLionel Sambuc A test2(B &x) {
112f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test35test2ERNS_1BE(
113f4a2713aSLionel Sambuc // CHECK: [[X:%.*]] = alloca [[B]]*,
114f4a2713aSLionel Sambuc // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]]
115f4a2713aSLionel Sambuc // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
116f4a2713aSLionel Sambuc // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
117f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[BOOL]]
118f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A:%.*]]* sret [[RESULT:%.*]], [[B]]* [[T0]])
119f4a2713aSLionel Sambuc // CHECK-NEXT: br label
120f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
121f4a2713aSLionel Sambuc // CHECK-NEXT: br label
122f4a2713aSLionel Sambuc // CHECK: ret void
123f4a2713aSLionel Sambuc return x ?: A();
124f4a2713aSLionel Sambuc }
125f4a2713aSLionel Sambuc
test3()126f4a2713aSLionel Sambuc A test3() {
127f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_ZN5test35test3Ev(
128f4a2713aSLionel Sambuc // CHECK: [[TEMP:%.*]] = alloca [[B]],
129f4a2713aSLionel Sambuc // CHECK-NEXT: call void @_ZN5test312test3_helperEv([[B]]* sret [[TEMP]])
130f4a2713aSLionel Sambuc // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
131f4a2713aSLionel Sambuc // CHECK-NEXT: br i1 [[BOOL]]
132f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A]]* sret [[RESULT:%.*]], [[B]]* [[TEMP]])
133f4a2713aSLionel Sambuc // CHECK-NEXT: br label
134f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31AC1Ev([[A]]* [[RESULT]])
135f4a2713aSLionel Sambuc // CHECK-NEXT: br label
136f4a2713aSLionel Sambuc // CHECK: call void @_ZN5test31BD1Ev([[B]]* [[TEMP]])
137f4a2713aSLionel Sambuc // CHECK-NEXT: ret void
138f4a2713aSLionel Sambuc extern B test3_helper();
139f4a2713aSLionel Sambuc return test3_helper() ?: A();
140f4a2713aSLionel Sambuc }
141f4a2713aSLionel Sambuc
142f4a2713aSLionel Sambuc }
143f4a2713aSLionel Sambuc
144f4a2713aSLionel Sambuc namespace test4 {
145f4a2713aSLionel Sambuc // Make sure this doesn't crash.
f()146f4a2713aSLionel Sambuc void f() {
147f4a2713aSLionel Sambuc const int a = 10, b = 20;
148f4a2713aSLionel Sambuc const int *c = &(a ?: b);
149f4a2713aSLionel Sambuc }
150f4a2713aSLionel Sambuc }
151