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