|  | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s | 
|  | // pr7726 | 
|  |  | 
|  | extern "C" int printf(...); | 
|  |  | 
|  | void test0() { | 
|  | // CHECK: call i32 (...) @printf({{.*}}, ptr noundef inttoptr (i64 3735928559 to ptr)) | 
|  | printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa); | 
|  | } | 
|  |  | 
|  | namespace radar8446940 { | 
|  | extern "C" void abort(); | 
|  |  | 
|  | void main () { | 
|  | char x[1]; | 
|  | char *y = x ? : 0; | 
|  |  | 
|  | if (x != y) | 
|  | abort(); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace radar8453812 { | 
|  | extern "C" void abort(); | 
|  | _Complex int getComplex(_Complex int val) { | 
|  | static int count; | 
|  | if (count++) | 
|  | abort(); | 
|  | return val; | 
|  | } | 
|  |  | 
|  | _Complex int cmplx() { | 
|  | _Complex int cond; | 
|  | _Complex int rhs; | 
|  |  | 
|  | return getComplex(1+2i) ? : rhs; | 
|  | } | 
|  |  | 
|  | // lvalue test | 
|  | void foo (int& lv) { | 
|  | ++lv; | 
|  | } | 
|  |  | 
|  | int global = 1; | 
|  |  | 
|  | int &cond() { | 
|  | static int count; | 
|  | if (count++) | 
|  | abort(); | 
|  | return global; | 
|  | } | 
|  |  | 
|  |  | 
|  | int main() { | 
|  | cmplx(); | 
|  | int rhs = 10; | 
|  | foo (cond()? : rhs); | 
|  | return  global-2; | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace test3 { | 
|  | struct A { | 
|  | A(); | 
|  | A(const A&); | 
|  | ~A(); | 
|  | }; | 
|  |  | 
|  | struct B { | 
|  | B(); | 
|  | B(const B&); | 
|  | ~B(); | 
|  | operator bool(); | 
|  | operator A(); | 
|  | }; | 
|  |  | 
|  | B test0(B &x) { | 
|  | // CHECK-LABEL:    define{{.*}} void @_ZN5test35test0ERNS_1BE( | 
|  | // CHECK:      [[RES:%.*]] = alloca ptr, | 
|  | // CHECK:      [[X:%.*]] = alloca ptr, | 
|  | // CHECK:      store ptr {{%.*}}, ptr [[RES]] | 
|  | // CHECK:      store ptr {{%.*}}, ptr [[X]] | 
|  | // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] | 
|  | // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[T0]]) | 
|  | // CHECK-NEXT: br i1 [[BOOL]] | 
|  | // CHECK:      call void @_ZN5test31BC1ERKS0_(ptr {{[^,]*}} [[RESULT:%.*]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[T0]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31BC1Ev(ptr {{[^,]*}} [[RESULT]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      ret void | 
|  | return x ?: B(); | 
|  | } | 
|  |  | 
|  | B test1() { | 
|  | // CHECK-LABEL:    define{{.*}} void @_ZN5test35test1Ev( | 
|  | // CHECK:      [[TEMP:%.*]] = alloca [[B:%.*]], | 
|  | // CHECK:      call  void @_ZN5test312test1_helperEv(ptr dead_on_unwind writable sret([[B]]) align 1 [[TEMP]]) | 
|  | // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[TEMP]]) | 
|  | // CHECK-NEXT: br i1 [[BOOL]] | 
|  | // CHECK:      call void @_ZN5test31BC1ERKS0_(ptr {{[^,]*}} [[RESULT:%.*]], ptr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) [[TEMP]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31BC1Ev(ptr {{[^,]*}} [[RESULT]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31BD1Ev(ptr {{[^,]*}} [[TEMP]]) | 
|  | // CHECK-NEXT: ret void | 
|  | extern B test1_helper(); | 
|  | return test1_helper() ?: B(); | 
|  | } | 
|  |  | 
|  |  | 
|  | A test2(B &x) { | 
|  | // CHECK-LABEL:    define{{.*}} void @_ZN5test35test2ERNS_1BE( | 
|  | // CHECK:      [[RES:%.*]] = alloca ptr, | 
|  | // CHECK:      [[X:%.*]] = alloca ptr, | 
|  | // CHECK:      store ptr {{%.*}}, ptr [[RES]] | 
|  | // CHECK:      store ptr {{%.*}}, ptr [[X]] | 
|  | // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] | 
|  | // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[T0]]) | 
|  | // CHECK-NEXT: br i1 [[BOOL]] | 
|  | // CHECK:      call void @_ZN5test31BcvNS_1AEEv(ptr dead_on_unwind writable sret([[A:%.*]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[T0]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31AC1Ev(ptr {{[^,]*}} [[RESULT]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      ret void | 
|  | return x ?: A(); | 
|  | } | 
|  |  | 
|  | A test3() { | 
|  | // CHECK-LABEL:    define{{.*}} void @_ZN5test35test3Ev( | 
|  | // CHECK:      [[TEMP:%.*]] = alloca [[B]], | 
|  | // CHECK:      call  void @_ZN5test312test3_helperEv(ptr dead_on_unwind writable sret([[B]]) align 1 [[TEMP]]) | 
|  | // CHECK-NEXT: [[BOOL:%.*]] = call noundef zeroext i1 @_ZN5test31BcvbEv(ptr {{[^,]*}} [[TEMP]]) | 
|  | // CHECK-NEXT: br i1 [[BOOL]] | 
|  | // CHECK:      call void @_ZN5test31BcvNS_1AEEv(ptr dead_on_unwind writable sret([[A]]) align 1 [[RESULT:%.*]], ptr {{[^,]*}} [[TEMP]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31AC1Ev(ptr {{[^,]*}} [[RESULT]]) | 
|  | // CHECK-NEXT: br label | 
|  | // CHECK:      call void @_ZN5test31BD1Ev(ptr {{[^,]*}} [[TEMP]]) | 
|  | // CHECK-NEXT: ret void | 
|  | extern B test3_helper(); | 
|  | return test3_helper() ?: A(); | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | namespace test4 { | 
|  | // Make sure this doesn't crash. | 
|  | void f() { | 
|  | const int a = 10, b = 20; | 
|  | const int *c = &(a ?: b); | 
|  | } | 
|  | } |