1 // RUN: %clang_cc1 -std=c++11 -triple armv7-none-eabi -fmerge-all-constants -emit-llvm -o - %s | FileCheck %s 2 3 // This creates and lifetime-extends a 'const char[5]' temporary. 4 // CHECK: @_ZGR19extended_string_ref_ = internal constant [5 x i8] c"hi\00\00\00", 5 // CHECK: @extended_string_ref ={{.*}} constant ptr @_ZGR19extended_string_ref_, 6 const char (&extended_string_ref)[5] = {"hi"}; 7 8 // This binds directly to a string literal object. 9 // CHECK: @nonextended_string_ref ={{.*}} constant ptr @.str 10 const char (&nonextended_string_ref)[3] = {"hi"}; 11 12 namespace reference { 13 struct A { 14 int i1, i2; 15 }; 16 17 void single_init() { 18 // No superfluous instructions allowed here, they could be 19 // hiding extra temporaries. 20 21 // CHECK: store i32 1, ptr 22 // CHECK-NEXT: store ptr %{{.*}}, ptr 23 const int &cri2a = 1; 24 25 // CHECK-NEXT: store i32 1, ptr 26 // CHECK-NEXT: store ptr %{{.*}}, ptr 27 const int &cri1a = {1}; 28 29 // CHECK-NEXT: store i32 1, ptr 30 int i = 1; 31 // CHECK-NEXT: store ptr %{{.*}}, ptr 32 int &ri1a = {i}; 33 34 // CHECK-NEXT: memcpy 35 A a{1, 2}; 36 // CHECK-NEXT: store ptr %{{.*}}, ptr % 37 A &ra1a = {a}; 38 39 using T = A&; 40 // CHECK-NEXT: store ptr %{{.*}}, ptr % 41 A &ra1b = T{a}; 42 43 // CHECK-NEXT: ret 44 } 45 46 void reference_to_aggregate(int i) { 47 // CHECK: getelementptr {{.*}}, i32 0, i32 0 48 // CHECK-NEXT: store i32 1 49 // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1 50 // CHECK-NEXT: %[[I1:.*]] = load i32, ptr 51 // CHECK-NEXT: store i32 %[[I1]] 52 // CHECK-NEXT: store ptr %{{.*}}, ptr %{{.*}}, align 53 const A &ra1{1, i}; 54 55 // CHECK-NEXT: getelementptr inbounds [3 x i32], ptr %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 56 // CHECK-NEXT: store i32 1 57 // CHECK-NEXT: getelementptr inbounds i32, ptr %{{.*}}, i{{32|64}} 1 58 // CHECK-NEXT: store i32 2 59 // CHECK-NEXT: getelementptr inbounds i32, ptr %{{.*}}, i{{32|64}} 1 60 // CHECK-NEXT: %[[I2:.*]] = load i32, ptr 61 // CHECK-NEXT: store i32 %[[I2]] 62 // CHECK-NEXT: store ptr %{{.*}}, ptr %{{.*}}, align 63 const int (&arrayRef)[] = {1, 2, i}; 64 65 // CHECK: store ptr @{{.*}}, ptr %{{.*}}, align 66 const A &constra1{1, 2}; 67 68 // CHECK-NEXT: store ptr @{{.*}}, ptr %{{.*}}, align 69 const int (&constarrayRef)[] = {1, 2, 3}; 70 71 // CHECK-NEXT: ret 72 } 73 74 struct B { 75 B(); 76 ~B(); 77 }; 78 79 void single_init_temp_cleanup() 80 { 81 // Ensure lifetime extension. 82 83 // CHECK: call noundef ptr @_ZN9reference1BC1Ev 84 // CHECK-NEXT: store ptr %{{.*}}, ptr % 85 const B &rb{ B() }; 86 // CHECK: call noundef ptr @_ZN9reference1BD1Ev 87 } 88 89 } 90 91 namespace PR23165 { 92 struct AbstractClass { 93 virtual void foo() const = 0; 94 }; 95 96 struct ChildClass : public AbstractClass { 97 virtual void foo() const {} 98 }; 99 100 void helper(const AbstractClass ¶m) { 101 param.foo(); 102 } 103 104 void foo() { 105 // CHECK-LABEL: @_ZN7PR231653fooEv 106 // CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev 107 // CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE 108 helper(ChildClass()); 109 } 110 111 struct S { struct T { int a; } t; mutable int b; }; 112 void f() { 113 // CHECK-LABEL: _ZN7PR231651fEv 114 // CHECK: alloca 115 // CHECK: alloca 116 // CHECK: store 117 const S::T &r = S().t; 118 } 119 } 120