diff options
Diffstat (limited to 'clang/test/CodeGenCXX/references.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/references.cpp | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/references.cpp b/clang/test/CodeGenCXX/references.cpp new file mode 100644 index 0000000..d315f71 --- /dev/null +++ b/clang/test/CodeGenCXX/references.cpp @@ -0,0 +1,313 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s +void t1() { + // CHECK: define void @_Z2t1v + // CHECK: [[REFLOAD:%.*]] = load i32** @a, align 8 + // CHECK: load i32* [[REFLOAD]], align 4 + extern int& a; + int b = a; +} + +void t2(int& a) { + // CHECK: define void @_Z2t2Ri + // CHECK: [[REFLOAD2:%.*]] = load i32** {{.*}}, align 8 + // CHECK: load i32* [[REFLOAD2]], align 4 + int b = a; +} + +int g; +int& gr = g; +int& grr = gr; +void t3() { + int b = gr; +} + +// Test reference binding. + +struct C { int a; }; +void f(const bool&); +void f(const int&); +void f(const _Complex int&); +void f(const C&); + +C aggregate_return(); + +bool& bool_reference_return(); +int& int_reference_return(); +_Complex int& complex_int_reference_return(); +C& aggregate_reference_return(); + +void test_bool() { + bool a = true; + f(a); + + f(true); + + bool_reference_return() = true; + a = bool_reference_return(); + + struct { const bool& b; } b = { true }; +} + +void test_scalar() { + int a = 10; + f(a); + + struct { int bitfield : 3; } s = { 3 }; + f(s.bitfield); + + f(10); + + __attribute((vector_size(16))) typedef int vec4; + f((vec4){1,2,3,4}[0]); + + int_reference_return() = 10; + a = int_reference_return(); + + struct { const int& a; } agg = { 10 }; +} + +void test_complex() { + _Complex int a = 10i; + f(a); + + f(10i); + + complex_int_reference_return() = 10i; + a = complex_int_reference_return(); + + struct { const _Complex int &a; } agg = { 10i }; +} + +void test_aggregate() { + C c; + f(c); + + f(aggregate_return()); + aggregate_reference_return().a = 10; + + c = aggregate_reference_return(); + + struct { const C& a; } agg = { C() }; +} + +int& reference_return() { + return g; +} + +int reference_decl() { + int& a = g; + const int& b = 1; + return a+b; +} + +struct A { + int& b(); +}; + +void f(A* a) { + int b = a->b(); +} + +// PR5122 +void *foo = 0; +void * const & kFoo = foo; + +struct D : C { D(); ~D(); }; + +void h() { + // CHECK: call void @_ZN1DD1Ev + const C& c = D(); +} + +namespace T { + struct A { + A(); + ~A(); + }; + + struct B { + B(); + ~B(); + A f(); + }; + + void f() { + // CHECK: call void @_ZN1T1BC1Ev + // CHECK: call void @_ZN1T1B1fEv + // CHECK: call void @_ZN1T1BD1Ev + const A& a = B().f(); + // CHECK: call void @_ZN1T1fEv + f(); + // CHECK: call void @_ZN1T1AD1Ev + } +} + +// PR5227. +namespace PR5227 { +void f(int &a) { + (a = 10) = 20; +} +} + +// PR5590 +struct s0; +struct s1 { struct s0 &s0; }; +void f0(s1 a) { s1 b = a; } + +// PR6024 +// CHECK: @_Z2f2v() +// CHECK: alloca i32, +// CHECK-NEXT: store +// CHECK-NEXT: ret +const int &f2() { return 0; } + +// Don't constant fold const reference parameters with default arguments to +// their default arguments. +namespace N1 { + const int foo = 1; + // CHECK: @_ZN2N14test + void test(const int& arg = foo) { + // Ensure this array is on the stack where we can set values instead of + // being a global constant. + // CHECK: %args_array = alloca + const int* const args_array[] = { &arg }; + } +} + +// Bind to subobjects while extending the life of the complete object. +namespace N2 { + class X { + public: + X(const X&); + X &operator=(const X&); + ~X(); + }; + + struct P { + X first; + }; + + P getP(); + + // CHECK: define void @_ZN2N21fEi + // CHECK: call void @_ZN2N24getPEv + // CHECK: getelementptr inbounds + // CHECK: store i32 17 + // CHECK: call void @_ZN2N21PD1Ev + void f(int i) { + const X& xr = getP().first; + i = 17; + } + + struct SpaceWaster { + int i, j; + }; + + struct ReallyHasX { + X x; + }; + + struct HasX : ReallyHasX { }; + + struct HasXContainer { + HasX has; + }; + + struct Y : SpaceWaster, HasXContainer { }; + struct Z : SpaceWaster, Y { }; + + Z getZ(); + + // CHECK: define void @_ZN2N21gEi + // CHECK: call void @_ZN2N24getZEv + // CHECK: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK: store i32 19 + // CHECK: call void @_ZN2N21ZD1Ev + // CHECK: ret void + void g(int i) { + const X &xr = getZ().has.x; + i = 19; + } +} + +namespace N3 { + +// PR7326 + +struct A { + explicit A(int); + ~A(); +}; + +// CHECK: define internal void @__cxx_global_var_init +// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E, i32 123) +// CHECK: call i32 @__cxa_atexit +// CHECK: ret void +const A &sA123 = A(123); +} + +namespace N4 { + +struct A { + A(); + ~A(); +}; + +void f() { + // CHECK: define void @_ZN2N41fEv + // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar) + // CHECK: call i32 @__cxa_atexit + // CHECK: ret void + static const A& ar = A(); + +} +} + +// PR9494 +namespace N5 { +struct AnyS { bool b; }; +void f(const bool&); +AnyS g(); +void h() { + // CHECK: call i8 @_ZN2N51gEv() + // CHECK: call void @_ZN2N51fERKb(i8* + f(g().b); +} +} + +// PR9565 +namespace PR9565 { + struct a { int a : 10, b : 10; }; + // CHECK: define void @_ZN6PR95651fEv() + void f() { + // CHECK: call void @llvm.memcpy + a x = { 0, 0 }; + // CHECK: [[WITH_SEVENTEEN:%[a-zA-Z0-9]+]] = or i32 [[WITHOUT_SEVENTEEN:%[a-zA-Z0-9]+]], 17 + // CHECK: store i32 [[WITH_SEVENTEEN]], i32* [[XA:%[a-zA-Z0-9]+]] + x.a = 17; + // CHECK-NEXT: bitcast + // CHECK-NEXT: load + // CHECK-NEXT: and + // CHECK-NEXT: shl + // CHECK-NEXT: ashr + // CHECK-NEXT: store i32 + // CHECK-NEXT: store i32* + const int &y = x.a; + // CHECK-NEXT: bitcast + // CHECK-NEXT: load + // CHECK-NEXT: and + // CHECK-NEXT: or + // CHECK-NEXT: store i32 + x.b = 19; + // CHECK-NEXT: ret void + } +} + +namespace N6 { + extern struct x {char& x;}y; + int a() { return y.x; } + // CHECK: define i32 @_ZN2N61aEv + // CHECK: [[REFLOAD3:%.*]] = load i8** getelementptr inbounds (%"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8 + // CHECK: load i8* [[REFLOAD3]], align 1 +} |