Files
llvm-project/clang/test/CodeGenCXX/cxx0x-initializer-references.cpp
Benjamin Kramer f3e67de85a [CodeGen] Do a more principled fix for PR231653, always use the inner type.
We were still using the MaterializeTemporaryExpr's type to check if the
transform is legal. Always use the inner Expr type.

llvm-svn: 234543
2015-04-09 22:50:07 +00:00

112 lines
2.8 KiB
C++

// RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
namespace reference {
struct A {
int i1, i2;
};
void single_init() {
// No superfluous instructions allowed here, they could be
// hiding extra temporaries.
// CHECK: store i32 1, i32*
// CHECK-NEXT: store i32* %{{.*}}, i32**
const int &cri2a = 1;
// CHECK-NEXT: store i32 1, i32*
// CHECK-NEXT: store i32* %{{.*}}, i32**
const int &cri1a = {1};
// CHECK-NEXT: store i32 1, i32*
int i = 1;
// CHECK-NEXT: store i32* %{{.*}}, i32**
int &ri1a = {i};
// CHECK-NEXT: bitcast
// CHECK-NEXT: memcpy
A a{1, 2};
// CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
A &ra1a = {a};
using T = A&;
// CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
A &ra1b = T{a};
// CHECK-NEXT: ret
}
void reference_to_aggregate(int i) {
// CHECK: getelementptr {{.*}}, i32 0, i32 0
// CHECK-NEXT: store i32 1
// CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1
// CHECK-NEXT: %[[I1:.*]] = load i32, i32*
// CHECK-NEXT: store i32 %[[I1]]
// CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align
const A &ra1{1, i};
// CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0
// CHECK-NEXT: store i32 1
// CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
// CHECK-NEXT: store i32 2
// CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1
// CHECK-NEXT: %[[I2:.*]] = load i32, i32*
// CHECK-NEXT: store i32 %[[I2]]
// CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align
const int (&arrayRef)[] = {1, 2, i};
// CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align
const A &constra1{1, 2};
// CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align
const int (&constarrayRef)[] = {1, 2, 3};
// CHECK-NEXT: ret
}
struct B {
B();
~B();
};
void single_init_temp_cleanup()
{
// Ensure lifetime extension.
// CHECK: call %"struct.reference::B"* @_ZN9reference1BC1Ev
// CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %
const B &rb{ B() };
// CHECK: call %"struct.reference::B"* @_ZN9reference1BD1Ev
}
}
namespace PR23165 {
struct AbstractClass {
virtual void foo() const = 0;
};
struct ChildClass : public AbstractClass {
virtual void foo() const {}
};
void helper(const AbstractClass &param) {
param.foo();
}
void foo() {
// CHECK-LABEL: @_ZN7PR231653fooEv
// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev
// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE
helper(ChildClass());
}
struct S { struct T { int a; } t; mutable int b; };
void f() {
// CHECK-LABEL: _ZN7PR231651fEv
// CHECK: alloca
// CHECK: alloca
// CHECK: store
const S::T &r = S().t;
}
}